Add SBType::IsAnonymousType() and relative plumbing in the debugger internals

For language that support such a thing, this API allows to ask whether a type is anonymous (i.e. has been given no name)

Comes with test case

llvm-svn: 252390
diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp
index dcdbbc7..90a2e65 100644
--- a/lldb/source/API/SBType.cpp
+++ b/lldb/source/API/SBType.cpp
@@ -264,6 +264,14 @@
     return m_opaque_sp->GetCompilerType(true).IsTypedefType();
 }
 
+bool
+SBType::IsAnonymousType ()
+{
+    if (!IsValid())
+        return false;
+    return m_opaque_sp->GetCompilerType(true).IsAnonymousType();
+}
+
 lldb::SBType
 SBType::GetFunctionReturnType ()
 {
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 3ac7378..11e587c 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -2585,6 +2585,38 @@
 }
 
 bool
+ClangASTContext::IsAnonymousType (lldb::opaque_compiler_type_t type)
+{
+    clang::QualType qual_type (GetCanonicalQualType(type));
+    
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+        {
+            if (const clang::RecordType *record_type = llvm::dyn_cast_or_null<clang::RecordType>(qual_type.getTypePtrOrNull()))
+            {
+                if (const clang::RecordDecl *record_decl = record_type->getDecl())
+                {
+                    return record_decl->isAnonymousStructOrUnion();
+                }
+            }
+            break;
+        }
+        case clang::Type::Elaborated:
+            return IsAnonymousType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+        case clang::Type::Typedef:
+            return IsAnonymousType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+        case clang::Type::Paren:
+            return IsAnonymousType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+        default:
+            break;
+    }
+    // The clang type does have a value
+    return false;
+}
+
+bool
 ClangASTContext::IsArrayType (lldb::opaque_compiler_type_t type,
                               CompilerType *element_type_ptr,
                               uint64_t *size,
diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp
index 061539a..e7cbe63 100644
--- a/lldb/source/Symbol/CompilerType.cpp
+++ b/lldb/source/Symbol/CompilerType.cpp
@@ -64,6 +64,14 @@
 }
 
 bool
+CompilerType::IsAnonymousType () const
+{
+    if (IsValid())
+        return m_type_system->IsAnonymousType(m_type);
+    return false;
+}
+
+bool
 CompilerType::IsArrayType (CompilerType *element_type_ptr,
                            uint64_t *size,
                            bool *is_incomplete) const
diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp
index eb44b29..5aa83b4 100644
--- a/lldb/source/Symbol/TypeSystem.cpp
+++ b/lldb/source/Symbol/TypeSystem.cpp
@@ -55,6 +55,12 @@
     return lldb::TypeSystemSP();
 }
 
+bool
+TypeSystem::IsAnonymousType (lldb::opaque_compiler_type_t type)
+{
+    return false;
+}
+
 CompilerType
 TypeSystem::GetLValueReferenceType (lldb::opaque_compiler_type_t type)
 {