diff --git a/src/AST/Class.cs b/src/AST/Class.cs
index 177e423c..b05c95ee 100644
--- a/src/AST/Class.cs
+++ b/src/AST/Class.cs
@@ -97,28 +97,6 @@ namespace CppSharp.AST
 
         public TagKind TagKind { get; set; }
 
-        public string Tag
-        {
-            get
-            {
-                switch (TagKind)
-                {
-                    case TagKind.Struct:
-                        return "struct";
-                    case TagKind.Interface:
-                        return "__interface";
-                    case TagKind.Union:
-                        return "union";
-                    case TagKind.Class:
-                        return "class";
-                    case TagKind.Enum:
-                        return "enum";
-                    default:
-                        throw new ArgumentOutOfRangeException(nameof(TagKind));
-                }
-            }
-        }
-
         // True if the class is final / sealed.
         public bool IsFinal { get; set; }
 
diff --git a/src/Generator/Generators/C/CppMarshal.cs b/src/Generator/Generators/C/CppMarshal.cs
index 593a4894..51e0c77a 100644
--- a/src/Generator/Generators/C/CppMarshal.cs
+++ b/src/Generator/Generators/C/CppMarshal.cs
@@ -269,7 +269,7 @@ namespace CppSharp.Generators.Cpp
                 Context.Return.Write($"({instance} == nullptr) ? nullptr : {MemoryAllocOperator} ");
 
             Context.Return.Write($"{QualifiedIdentifier(@class)}(");
-            Context.Return.Write($"({@class.Tag} ::{@class.QualifiedOriginalName}*)");
+            Context.Return.Write($"({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)");
             Context.Return.Write($"{instance})");
         }
 
@@ -580,7 +580,8 @@ namespace CppSharp.Generators.Cpp
                 && method.Conversion == MethodConversionKind.FunctionToInstanceMethod
                 && Context.ParameterIndex == 0)
             {
-                Context.Return.Write($"({@class.Tag} ::{@class.QualifiedOriginalName}*)");
+                Context.Return.Write($@"({typePrinter.PrintTag(@class)}::{
+                    @class.QualifiedOriginalName}*)");
                 Context.Return.Write(Helpers.InstanceIdentifier);
                 return;
             }
@@ -588,8 +589,8 @@ namespace CppSharp.Generators.Cpp
             var paramType = Context.Parameter.Type.Desugar();
             var isPointer = paramType.SkipPointerRefs().IsPointer();
             var deref = isPointer ? "->" : ".";
-            var instance = $"({@class.Tag} ::{@class.QualifiedOriginalName}*)" +
-                $"{Context.Parameter.Name}{deref}{Helpers.InstanceIdentifier}";
+            var instance = $"({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)" +
+                Context.Parameter.Name + deref + Helpers.InstanceIdentifier;
 
             if (isPointer)
                 Context.Return.Write($"{Context.Parameter.Name} ? {instance} : nullptr");
diff --git a/src/Generator/Generators/C/CppSources.cs b/src/Generator/Generators/C/CppSources.cs
index f64e2a03..b4ed3719 100644
--- a/src/Generator/Generators/C/CppSources.cs
+++ b/src/Generator/Generators/C/CppSources.cs
@@ -294,7 +294,7 @@ namespace CppSharp.Generators.Cpp
         {
             Write($"{QualifiedIdentifier(@class)}::{@class.Name}(");
 
-            var nativeType = $"{@class.Tag} ::{@class.QualifiedOriginalName}*";
+            var nativeType = $"{typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*";
             //WriteLine($"{nativeType} {ClassCtorInstanceParamIdentifier})");
             WriteLine(!withOwnNativeInstanceParam ? $"{nativeType} {ClassCtorInstanceParamIdentifier})" :
                 $"{nativeType} {ClassCtorInstanceParamIdentifier}, bool ownNativeInstance)");
@@ -412,7 +412,7 @@ namespace CppSharp.Generators.Cpp
                         PushBlock(BlockKind.ConstructorBody, @class);
 
                         var @params = GenerateFunctionParamsMarshal(method.Parameters, method);
-                        Write($@"{Helpers.InstanceIdentifier} = new {@class.Tag} ::{
+                        Write($@"{Helpers.InstanceIdentifier} = new {typePrinter.PrintTag(@class)}::{
                             method.Namespace.QualifiedOriginalName}(");
                         GenerateFunctionParams(@params);
                         WriteLine(");");
@@ -492,7 +492,8 @@ namespace CppSharp.Generators.Cpp
             var field = property?.Field;
             if (field != null)
             {
-                Write($"(({@class.Tag} ::{@class.QualifiedOriginalName}*){Helpers.InstanceIdentifier})->");
+                Write($@"(({typePrinter.PrintTag(@class)}::{
+                    @class.QualifiedOriginalName}*){Helpers.InstanceIdentifier})->");
                 Write($"{field.OriginalName}");
 
                 var isGetter = property.GetMethod == method;
@@ -510,7 +511,8 @@ namespace CppSharp.Generators.Cpp
                 else
                 {
                     if (IsNativeMethod(function))
-                        Write($"(({@class.Tag} ::{@class.QualifiedOriginalName}*){Helpers.InstanceIdentifier})->");
+                        Write($@"(({typePrinter.PrintTag(@class)}::{
+                            @class.QualifiedOriginalName}*){Helpers.InstanceIdentifier})->");
 
                     Write($"{base.GetMethodIdentifier(function, TypePrinterContextKind.Native)}(");
                 }
diff --git a/src/Generator/Generators/C/CppTypePrinter.cs b/src/Generator/Generators/C/CppTypePrinter.cs
index a379b183..f6458a93 100644
--- a/src/Generator/Generators/C/CppTypePrinter.cs
+++ b/src/Generator/Generators/C/CppTypePrinter.cs
@@ -739,19 +739,27 @@ namespace CppSharp.Generators.C
             return VisitDeclaration(template);
         }
 
-        private string GetStringQuals(TypeQualifiers quals, bool appendSpace = true)
+        public string PrintTag(Class @class)
         {
-            var stringQuals = new List<string>();
-            if (PrintTypeQualifiers)
+            if (@class.Namespace.Typedefs.Any(t => t.Name == @class.Name))
             {
-                if (quals.IsConst)
-                    stringQuals.Add("const");
-                if (quals.IsVolatile)
-                    stringQuals.Add("volatile");
-            }
-            if (stringQuals.Count == 0)
                 return string.Empty;
-            return string.Join(" ", stringQuals) + (appendSpace ? " " : string.Empty);
+            }
+            switch (@class.TagKind)
+            {
+                case TagKind.Struct:
+                    return "struct ";
+                case TagKind.Interface:
+                    return "__interface ";
+                case TagKind.Union:
+                    return "union ";
+                case TagKind.Class:
+                    return "class ";
+                case TagKind.Enum:
+                    return "enum ";
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(@class.TagKind));
+            }
         }
 
         private static string Print(ExceptionSpecType exceptionSpecType)
@@ -769,5 +777,20 @@ namespace CppSharp.Generators.C
                     return string.Empty;
             }
         }
+
+        private string GetStringQuals(TypeQualifiers quals, bool appendSpace = true)
+        {
+            var stringQuals = new List<string>();
+            if (PrintTypeQualifiers)
+            {
+                if (quals.IsConst)
+                    stringQuals.Add("const");
+                if (quals.IsVolatile)
+                    stringQuals.Add("volatile");
+            }
+            if (stringQuals.Count == 0)
+                return string.Empty;
+            return string.Join(" ", stringQuals) + (appendSpace ? " " : string.Empty);
+        }
     }
 }
diff --git a/src/Generator/Generators/CLI/CLIHeaders.cs b/src/Generator/Generators/CLI/CLIHeaders.cs
index 06cb8ab4..e71e77c1 100644
--- a/src/Generator/Generators/CLI/CLIHeaders.cs
+++ b/src/Generator/Generators/CLI/CLIHeaders.cs
@@ -261,7 +261,7 @@ namespace CppSharp.Generators.CLI
             GenerateDeclContext(@class);
             Unindent();
 
-            string nativeType = $"{@class.Tag} ::{@class.QualifiedOriginalName}*";
+            string nativeType = $"{typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*";
 
             if (CLIGenerator.ShouldGenerateClassNativeField(@class))
                 GenerateClassNativeField(nativeType);
diff --git a/src/Generator/Generators/CLI/CLIMarshal.cs b/src/Generator/Generators/CLI/CLIMarshal.cs
index e0668524..c89f84cf 100644
--- a/src/Generator/Generators/CLI/CLIMarshal.cs
+++ b/src/Generator/Generators/CLI/CLIMarshal.cs
@@ -279,7 +279,7 @@ namespace CppSharp.Generators.CLI
             if (@class.IsRefType && needsCopy)
             {
                 var name = Generator.GeneratedIdentifier(Context.ReturnVarName);
-                Context.Before.WriteLine($"auto {name} = new {@class.Tag} ::{@class.QualifiedOriginalName}({Context.ReturnVarName});");
+                Context.Before.WriteLine($"auto {name} = new {typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}({Context.ReturnVarName});");
                 instance = name;
 
                 ownNativeInstance = true;
@@ -304,7 +304,7 @@ namespace CppSharp.Generators.CLI
                     instance);
 
             Context.Return.Write("::{0}(", QualifiedIdentifier(@class));
-            Context.Return.Write($"({@class.Tag} ::{@class.QualifiedOriginalName}*)");
+            Context.Return.Write($"({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)");
             Context.Return.Write("{0}{1})", instance, ownNativeInstance ? ", true" : "");
         }
 
@@ -723,12 +723,12 @@ namespace CppSharp.Generators.CLI
                 && method.Conversion == MethodConversionKind.FunctionToInstanceMethod
                 && Context.ParameterIndex == 0)
             {
-                Context.Return.Write($"({@class.Tag} ::{@class.QualifiedOriginalName}*)");
+                Context.Return.Write($"({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)");
                 Context.Return.Write("NativePtr");
                 return;
             }
 
-            Context.Return.Write($"({@class.Tag} ::{@class.QualifiedOriginalName}*)");
+            Context.Return.Write($"({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)");
             Context.Return.Write("{0}->NativePtr", Context.Parameter.Name);
         }
 
diff --git a/src/Generator/Generators/CLI/CLISources.cs b/src/Generator/Generators/CLI/CLISources.cs
index f86ce9e8..06f512c3 100644
--- a/src/Generator/Generators/CLI/CLISources.cs
+++ b/src/Generator/Generators/CLI/CLISources.cs
@@ -145,7 +145,7 @@ namespace CppSharp.Generators.CLI
                 WriteLine("void {0}::{1}::set(::System::IntPtr object)",
                     qualifiedIdentifier, Helpers.InstanceIdentifier);
                 WriteOpenBraceAndIndent();
-                var nativeType = $"{@class.Tag} ::{@class.QualifiedOriginalName}*";
+                var nativeType = $"{typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*";
                 WriteLine("NativePtr = ({0})object.ToPointer();", nativeType);
                 UnindentAndWriteCloseBrace();
                 PopBlock(NewLineKind.BeforeNextBlock);
@@ -258,7 +258,7 @@ namespace CppSharp.Generators.CLI
                 WriteOpenBraceAndIndent();
                 WriteLine("auto __nativePtr = NativePtr;");
                 WriteLine("NativePtr = 0;");
-                WriteLine($"delete ({@class.Tag} ::{@class.QualifiedOriginalName}*) __nativePtr;", @class.QualifiedOriginalName);
+                WriteLine($"delete ({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*) __nativePtr;", @class.QualifiedOriginalName);
                 UnindentAndWriteCloseBrace();
             }
 
@@ -396,7 +396,7 @@ namespace CppSharp.Generators.CLI
                 if (decl is Variable)
                     variable = $"::{@class.QualifiedOriginalName}::{decl.OriginalName}";
                 else
-                    variable = $"(({@class.Tag} ::{@class.QualifiedOriginalName}*)NativePtr)->{decl.OriginalName}";
+                    variable = $"(({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)NativePtr)->{decl.OriginalName}";
 
                 var ctx = new MarshalContext(Context, CurrentIndentation)
                 {
@@ -484,7 +484,7 @@ namespace CppSharp.Generators.CLI
                 else if (CLIGenerator.ShouldGenerateClassNativeField(@class))
                     variable = $"NativePtr->{decl.OriginalName}";
                 else
-                    variable = $"(({@class.Tag} ::{@class.QualifiedOriginalName}*)NativePtr)->{decl.OriginalName}";
+                    variable = $"(({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)NativePtr)->{decl.OriginalName}";
 
                 var ctx = new MarshalContext(Context, CurrentIndentation)
                 {
@@ -542,7 +542,7 @@ namespace CppSharp.Generators.CLI
             WriteLine("auto _fptr = (void (*)({0}))Marshal::GetFunctionPointerForDelegate({1}Instance).ToPointer();",
                 args, delegateName);
 
-            WriteLine($"(({@class.Tag} ::{@class.QualifiedOriginalName}*)NativePtr)->{@event.OriginalName}.Connect(_fptr);");
+            WriteLine($"(({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)NativePtr)->{@event.OriginalName}.Connect(_fptr);");
 
             UnindentAndWriteCloseBrace();
 
@@ -627,7 +627,7 @@ namespace CppSharp.Generators.CLI
 
             Write("{0}::{1}(", qualifiedIdentifier, @class.Name);
 
-            string nativeType = $"{@class.Tag} ::{@class.QualifiedOriginalName}*";
+            string nativeType = $"{typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*";
             WriteLine(!withOwnNativeInstanceParam ? "{0} native)" : "{0} native, bool ownNativeInstance)", nativeType);
 
             var hasBase = GenerateClassConstructorBase(@class, null, withOwnNativeInstanceParam);
@@ -781,7 +781,7 @@ namespace CppSharp.Generators.CLI
                     if (!@class.IsAbstract)
                     {
                         var @params = GenerateFunctionParamsMarshal(method.Parameters, method);
-                        Write($@"NativePtr = new {@class.Tag} ::{
+                        Write($@"NativePtr = new {typePrinter.PrintTag(@class)}::{
                             @class.QualifiedOriginalName}(");
                         GenerateFunctionParams(@params);
                         WriteLine(");");
@@ -865,7 +865,7 @@ namespace CppSharp.Generators.CLI
                 names.Add(marshal.Context.Return);
             }
 
-            WriteLine($@"{@class.Tag} ::{
+            WriteLine($@"{typePrinter.PrintTag(@class)}::{
                 @class.QualifiedOriginalName} _native({string.Join(", ", names)});");
 
             GenerateValueTypeConstructorCallProperties(@class);
@@ -957,7 +957,7 @@ namespace CppSharp.Generators.CLI
             var isValueType = @class != null && @class.IsValueType;
             if (isValueType && !IsNativeFunctionOrStaticMethod(function))
             {
-                WriteLine($"auto {valueMarshalName} = {@class.Tag} ::{@class.QualifiedOriginalName}();");
+                WriteLine($"auto {valueMarshalName} = {typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}();");
 
                 var param = new Parameter { Name = "(*this)" , Namespace = function.Namespace };
                 var ctx = new MarshalContext(Context, CurrentIndentation)
@@ -1015,7 +1015,7 @@ namespace CppSharp.Generators.CLI
                     if (isValueType)
                         Write($"{valueMarshalName}.");
                     else if (IsNativeMethod(function))
-                        Write($"(({@class.Tag} ::{@class.QualifiedOriginalName}*)NativePtr)->");
+                        Write($"(({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)NativePtr)->");
                     Write("{0}(", function.OriginalName);
                 }