[SymbolFilePDB] Add support for CVR pointer type qualifier

Summary:
- Complete element type of PDBSymbolTypeArray.

- Add a test to check types of multi-dimensional array and pointers with CVR.

Reviewers: zturner, rnk, lldb-commits

Reviewed By: zturner

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D44167

llvm-svn: 326859
diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 4a73649..9761bae 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -292,6 +292,9 @@
         m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID());
     CompilerType ast_typedef =
         m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx);
+    if (!ast_typedef)
+      return nullptr;
+
     return std::make_shared<lldb_private::Type>(
         type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
         bytes, nullptr, target_type->GetID(),
@@ -365,20 +368,35 @@
     auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type);
     assert(array_type);
     uint32_t num_elements = array_type->getCount();
-    uint32_t element_uid = array_type->getElementType()->getSymIndexId();
+    uint32_t element_uid = array_type->getElementTypeId();
     uint32_t bytes = array_type->getLength();
 
+    // If array rank > 0, PDB gives the element type at N=0. So element type
+    // will parsed in the order N=0, N=1,..., N=rank sequentially.
     lldb_private::Type *element_type =
         m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
     if (!element_type)
       return nullptr;
-    CompilerType element_ast_type = element_type->GetFullCompilerType();
+
+    CompilerType element_ast_type = element_type->GetForwardCompilerType();
+    // If element type is UDT, it needs to be complete.
+    if (ClangASTContext::IsCXXClassType(element_ast_type) &&
+        element_ast_type.GetCompleteType() == false) {
+      if (ClangASTContext::StartTagDeclarationDefinition(element_ast_type)) {
+        ClangASTContext::CompleteTagDeclarationDefinition(element_ast_type);
+      } else {
+        // We are not able to start defintion.
+        return nullptr;
+      }
+    }
     CompilerType array_ast_type =
-        m_ast.CreateArrayType(element_ast_type, num_elements, false);
-    return std::make_shared<lldb_private::Type>(
+        m_ast.CreateArrayType(element_ast_type, num_elements, /*is_gnu_vector*/false);
+    TypeSP type_sp = std::make_shared<lldb_private::Type>(
         array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
         bytes, nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
         decl, array_ast_type, lldb_private::Type::eResolveStateFull);
+    type_sp->SetEncodingType(element_type);
+    return type_sp;
   } break;
   case PDB_SymType::BuiltinType: {
     auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type);
@@ -392,20 +410,17 @@
     CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize(
         &m_ast, builtin_type, encoding, bytes * 8);
 
-    Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
-    if (builtin_type->isConstType()) {
-      encoding_data_type = Type::eEncodingIsConstUID;
+    if (builtin_type->isConstType())
       builtin_ast_type = builtin_ast_type.AddConstModifier();
-    }
-    if (builtin_type->isVolatileType()) {
-      encoding_data_type = Type::eEncodingIsVolatileUID;
+
+    if (builtin_type->isVolatileType())
       builtin_ast_type = builtin_ast_type.AddVolatileModifier();
-    }
+
     auto type_name = GetPDBBuiltinTypeName(builtin_type, builtin_ast_type);
 
     return std::make_shared<lldb_private::Type>(
         builtin_type->getSymIndexId(), m_ast.GetSymbolFile(), type_name,
-        bytes, nullptr, LLDB_INVALID_UID, encoding_data_type,
+        bytes, nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
         decl, builtin_ast_type, lldb_private::Type::eResolveStateFull);
   } break;
   case PDB_SymType::PointerType: {
@@ -417,18 +432,27 @@
       return nullptr;
 
     CompilerType pointer_ast_type;
-    Type::EncodingDataType encoding_data_type = Type::eEncodingIsPointerUID;
-    if (pointer_type->isReference()) {
-      encoding_data_type = Type::eEncodingIsLValueReferenceUID;
-      pointer_ast_type =
-          pointee_type->GetFullCompilerType().GetLValueReferenceType();
-    } else
-      pointer_ast_type = pointee_type->GetFullCompilerType().GetPointerType();
+    pointer_ast_type = pointee_type->GetFullCompilerType();
+    if (pointer_type->isReference())
+      pointer_ast_type = pointer_ast_type.GetLValueReferenceType();
+    else if (pointer_type->getRawSymbol().isRValueReference())
+      pointer_ast_type = pointer_ast_type.GetRValueReferenceType();
+    else
+      pointer_ast_type = pointer_ast_type.GetPointerType();
+
+    if (pointer_type->isConstType())
+      pointer_ast_type = pointer_ast_type.AddConstModifier();
+
+    if (pointer_type->isVolatileType())
+      pointer_ast_type = pointer_ast_type.AddVolatileModifier();
+
+    if (pointer_type->getRawSymbol().isRestrictedType())
+      pointer_ast_type = pointer_ast_type.AddRestrictModifier();
 
     return std::make_shared<lldb_private::Type>(
         pointer_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
         pointer_type->getLength(), nullptr, LLDB_INVALID_UID,
-        encoding_data_type, decl, pointer_ast_type,
+        lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type,
         lldb_private::Type::eResolveStateFull);
   } break;
   default: break;