Author: zturner Date: Fri Apr 1 18:20:35 2016 New Revision: 265200 URL: http://llvm.org/viewvc/llvm-project?rev=265200&view=rev Log: Add some unit tests for ClangASTContext.
In doing so, two bugs were uncovered (and fixed). The first bug is that ClangASTContext::RemoveFastQualifiers() was broken, and was not removing fast qualifiers (or doing anything else for that matter). The second bug is that UnifyAccessSpecifiers treated AS_None asymmetrically, which is probably an edge case, but seems like a bug nonetheless. Added: lldb/trunk/unittests/Symbol/ lldb/trunk/unittests/Symbol/CMakeLists.txt lldb/trunk/unittests/Symbol/TestClangASTContext.cpp Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h lldb/trunk/source/Symbol/ClangASTContext.cpp lldb/trunk/source/Symbol/ClangUtil.cpp lldb/trunk/unittests/CMakeLists.txt Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=265200&r1=265199&r2=265200&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Fri Apr 1 18:20:35 2016 @@ -1151,23 +1151,26 @@ public: clang::VarDecl * CreateVariableDeclaration (clang::DeclContext *decl_context, const char *name, clang::QualType type); -protected: + static lldb::opaque_compiler_type_t + GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type); + static clang::QualType - GetQualType (lldb::opaque_compiler_type_t type) + GetQualType(lldb::opaque_compiler_type_t type) { if (type) return clang::QualType::getFromOpaquePtr(type); return clang::QualType(); } - + static clang::QualType - GetCanonicalQualType (lldb::opaque_compiler_type_t type) + GetCanonicalQualType(lldb::opaque_compiler_type_t type) { if (type) return clang::QualType::getFromOpaquePtr(type).getCanonicalType(); return clang::QualType(); } +protected: //------------------------------------------------------------------ // Classes that inherit from ClangASTContext can see and modify these //------------------------------------------------------------------ Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=265200&r1=265199&r2=265200&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Apr 1 18:20:35 2016 @@ -911,113 +911,12 @@ ClangASTContext::GetBasicType (lldb::Bas CompilerType ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type) { - if (ast) - { - lldb::opaque_compiler_type_t clang_type = nullptr; - - switch (basic_type) - { - case eBasicTypeInvalid: - case eBasicTypeOther: - break; - case eBasicTypeVoid: - clang_type = ast->VoidTy.getAsOpaquePtr(); - break; - case eBasicTypeChar: - clang_type = ast->CharTy.getAsOpaquePtr(); - break; - case eBasicTypeSignedChar: - clang_type = ast->SignedCharTy.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedChar: - clang_type = ast->UnsignedCharTy.getAsOpaquePtr(); - break; - case eBasicTypeWChar: - clang_type = ast->getWCharType().getAsOpaquePtr(); - break; - case eBasicTypeSignedWChar: - clang_type = ast->getSignedWCharType().getAsOpaquePtr(); - break; - case eBasicTypeUnsignedWChar: - clang_type = ast->getUnsignedWCharType().getAsOpaquePtr(); - break; - case eBasicTypeChar16: - clang_type = ast->Char16Ty.getAsOpaquePtr(); - break; - case eBasicTypeChar32: - clang_type = ast->Char32Ty.getAsOpaquePtr(); - break; - case eBasicTypeShort: - clang_type = ast->ShortTy.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedShort: - clang_type = ast->UnsignedShortTy.getAsOpaquePtr(); - break; - case eBasicTypeInt: - clang_type = ast->IntTy.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedInt: - clang_type = ast->UnsignedIntTy.getAsOpaquePtr(); - break; - case eBasicTypeLong: - clang_type = ast->LongTy.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedLong: - clang_type = ast->UnsignedLongTy.getAsOpaquePtr(); - break; - case eBasicTypeLongLong: - clang_type = ast->LongLongTy.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedLongLong: - clang_type = ast->UnsignedLongLongTy.getAsOpaquePtr(); - break; - case eBasicTypeInt128: - clang_type = ast->Int128Ty.getAsOpaquePtr(); - break; - case eBasicTypeUnsignedInt128: - clang_type = ast->UnsignedInt128Ty.getAsOpaquePtr(); - break; - case eBasicTypeBool: - clang_type = ast->BoolTy.getAsOpaquePtr(); - break; - case eBasicTypeHalf: - clang_type = ast->HalfTy.getAsOpaquePtr(); - break; - case eBasicTypeFloat: - clang_type = ast->FloatTy.getAsOpaquePtr(); - break; - case eBasicTypeDouble: - clang_type = ast->DoubleTy.getAsOpaquePtr(); - break; - case eBasicTypeLongDouble: - clang_type = ast->LongDoubleTy.getAsOpaquePtr(); - break; - case eBasicTypeFloatComplex: - clang_type = ast->FloatComplexTy.getAsOpaquePtr(); - break; - case eBasicTypeDoubleComplex: - clang_type = ast->DoubleComplexTy.getAsOpaquePtr(); - break; - case eBasicTypeLongDoubleComplex: - clang_type = ast->LongDoubleComplexTy.getAsOpaquePtr(); - break; - case eBasicTypeObjCID: - clang_type = ast->getObjCIdType().getAsOpaquePtr(); - break; - case eBasicTypeObjCClass: - clang_type = ast->getObjCClassType().getAsOpaquePtr(); - break; - case eBasicTypeObjCSel: - clang_type = ast->getObjCSelType().getAsOpaquePtr(); - break; - case eBasicTypeNullPtr: - clang_type = ast->NullPtrTy.getAsOpaquePtr(); - break; - } - - if (clang_type) - return CompilerType (GetASTContext(ast), clang_type); - } + if (!ast) + return CompilerType(); + lldb::opaque_compiler_type_t clang_type = GetOpaqueCompilerType(ast, basic_type); + + if (clang_type) + return CompilerType(GetASTContext(ast), clang_type); return CompilerType(); } @@ -1662,25 +1561,14 @@ ClangASTContext::CheckOverloadedOperator clang::AccessSpecifier ClangASTContext::UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs) { - clang::AccessSpecifier ret = lhs; - // Make the access equal to the stricter of the field and the nested field's access - switch (ret) - { - case clang::AS_none: - break; - case clang::AS_private: - break; - case clang::AS_protected: - if (rhs == AS_private) - ret = AS_private; - break; - case clang::AS_public: - ret = rhs; - break; - } - - return ret; + if (lhs == AS_none || rhs == AS_none) + return AS_none; + if (lhs == AS_private || rhs == AS_private) + return AS_private; + if (lhs == AS_protected || rhs == AS_protected) + return AS_protected; + return AS_public; } bool @@ -1998,6 +1886,78 @@ ClangASTContext::CreateVariableDeclarati return nullptr; } +lldb::opaque_compiler_type_t +ClangASTContext::GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type) +{ + switch (basic_type) + { + case eBasicTypeVoid: + return ast->VoidTy.getAsOpaquePtr(); + case eBasicTypeChar: + return ast->CharTy.getAsOpaquePtr(); + case eBasicTypeSignedChar: + return ast->SignedCharTy.getAsOpaquePtr(); + case eBasicTypeUnsignedChar: + return ast->UnsignedCharTy.getAsOpaquePtr(); + case eBasicTypeWChar: + return ast->getWCharType().getAsOpaquePtr(); + case eBasicTypeSignedWChar: + return ast->getSignedWCharType().getAsOpaquePtr(); + case eBasicTypeUnsignedWChar: + return ast->getUnsignedWCharType().getAsOpaquePtr(); + case eBasicTypeChar16: + return ast->Char16Ty.getAsOpaquePtr(); + case eBasicTypeChar32: + return ast->Char32Ty.getAsOpaquePtr(); + case eBasicTypeShort: + return ast->ShortTy.getAsOpaquePtr(); + case eBasicTypeUnsignedShort: + return ast->UnsignedShortTy.getAsOpaquePtr(); + case eBasicTypeInt: + return ast->IntTy.getAsOpaquePtr(); + case eBasicTypeUnsignedInt: + return ast->UnsignedIntTy.getAsOpaquePtr(); + case eBasicTypeLong: + return ast->LongTy.getAsOpaquePtr(); + case eBasicTypeUnsignedLong: + return ast->UnsignedLongTy.getAsOpaquePtr(); + case eBasicTypeLongLong: + return ast->LongLongTy.getAsOpaquePtr(); + case eBasicTypeUnsignedLongLong: + return ast->UnsignedLongLongTy.getAsOpaquePtr(); + case eBasicTypeInt128: + return ast->Int128Ty.getAsOpaquePtr(); + case eBasicTypeUnsignedInt128: + return ast->UnsignedInt128Ty.getAsOpaquePtr(); + case eBasicTypeBool: + return ast->BoolTy.getAsOpaquePtr(); + case eBasicTypeHalf: + return ast->HalfTy.getAsOpaquePtr(); + case eBasicTypeFloat: + return ast->FloatTy.getAsOpaquePtr(); + case eBasicTypeDouble: + return ast->DoubleTy.getAsOpaquePtr(); + case eBasicTypeLongDouble: + return ast->LongDoubleTy.getAsOpaquePtr(); + case eBasicTypeFloatComplex: + return ast->FloatComplexTy.getAsOpaquePtr(); + case eBasicTypeDoubleComplex: + return ast->DoubleComplexTy.getAsOpaquePtr(); + case eBasicTypeLongDoubleComplex: + return ast->LongDoubleComplexTy.getAsOpaquePtr(); + case eBasicTypeObjCID: + return ast->getObjCIdType().getAsOpaquePtr(); + case eBasicTypeObjCClass: + return ast->getObjCClassType().getAsOpaquePtr(); + case eBasicTypeObjCSel: + return ast->getObjCSelType().getAsOpaquePtr(); + case eBasicTypeNullPtr: + return ast->NullPtrTy.getAsOpaquePtr(); + default: + return nullptr; + } +} + #pragma mark Function Types FunctionDecl * @@ -5824,7 +5784,8 @@ ClangASTContext::GetVirtualBaseClassAtIn return GetVirtualBaseClassAtIndex (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), idx, bit_offset_ptr); case clang::Type::Paren: - return GetVirtualBaseClassAtIndex (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx, bit_offset_ptr); + return GetVirtualBaseClassAtIndex(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx, + bit_offset_ptr); default: break; @@ -9583,7 +9544,7 @@ ClangASTContext::DeclGetFunctionNumArgum if (clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>((clang::Decl*)opaque_decl)) return func_decl->param_size(); if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl)) - return objc_method->param_size(); + return objc_method->param_size(); else return 0; } @@ -9597,7 +9558,7 @@ ClangASTContext::DeclGetFunctionArgument { ParmVarDecl *var_decl = func_decl->getParamDecl(idx); if (var_decl) - return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr()); + return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr()); } } else if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl)) Modified: lldb/trunk/source/Symbol/ClangUtil.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangUtil.cpp?rev=265200&r1=265199&r2=265200&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangUtil.cpp (original) +++ lldb/trunk/source/Symbol/ClangUtil.cpp Fri Apr 1 18:20:35 2016 @@ -53,6 +53,6 @@ ClangUtil::RemoveFastQualifiers(const Co return ct; QualType qual_type(GetQualType(ct)); - qual_type.getQualifiers().removeFastQualifiers(); + qual_type.removeLocalFastQualifiers(); return CompilerType(ct.GetTypeSystem(), qual_type.getAsOpaquePtr()); } Modified: lldb/trunk/unittests/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/CMakeLists.txt?rev=265200&r1=265199&r2=265200&view=diff ============================================================================== --- lldb/trunk/unittests/CMakeLists.txt (original) +++ lldb/trunk/unittests/CMakeLists.txt Fri Apr 1 18:20:35 2016 @@ -44,5 +44,6 @@ add_subdirectory(Expression) add_subdirectory(Host) add_subdirectory(Interpreter) add_subdirectory(ScriptInterpreter) +add_subdirectory(Symbol) add_subdirectory(SymbolFile) add_subdirectory(Utility) Added: lldb/trunk/unittests/Symbol/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Symbol/CMakeLists.txt?rev=265200&view=auto ============================================================================== --- lldb/trunk/unittests/Symbol/CMakeLists.txt (added) +++ lldb/trunk/unittests/Symbol/CMakeLists.txt Fri Apr 1 18:20:35 2016 @@ -0,0 +1,3 @@ +add_lldb_unittest(SymbolTests + TestClangASTContext.cpp + ) Added: lldb/trunk/unittests/Symbol/TestClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Symbol/TestClangASTContext.cpp?rev=265200&view=auto ============================================================================== --- lldb/trunk/unittests/Symbol/TestClangASTContext.cpp (added) +++ lldb/trunk/unittests/Symbol/TestClangASTContext.cpp Fri Apr 1 18:20:35 2016 @@ -0,0 +1,315 @@ +//===-- TestClangASTContext.cpp ---------------------------------------*- C++ -*-===// + +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangUtil.h" +#include "lldb/Symbol/Declaration.h" +#include "lldb/Symbol/GoASTContext.h" + +using namespace clang; +using namespace lldb; +using namespace lldb_private; + +class TestClangASTContext : public testing::Test +{ +public: + static void + SetUpTestCase() + { + HostInfo::Initialize(); + } + + static void + TearDownTestCase() + { + HostInfo::Terminate(); + } + + virtual void + SetUp() override + { + std::string triple = HostInfo::GetTargetTriple(); + m_ast.reset(new ClangASTContext(triple.c_str())); + } + + virtual void + TearDown() override + { + m_ast.reset(); + } + +protected: + std::unique_ptr<ClangASTContext> m_ast; + + QualType + GetBasicQualType(BasicType type) const + { + return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type)); + } + + QualType + GetBasicQualType(const char *name) const + { + return ClangUtil::GetQualType(m_ast->GetBuiltinTypeByName(ConstString(name))); + } +}; + +TEST_F(TestClangASTContext, TestGetBasicTypeFromEnum) +{ + clang::ASTContext *context = m_ast->getASTContext(); + + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeBool), context->BoolTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeChar), context->CharTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeChar16), context->Char16Ty)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeChar32), context->Char32Ty)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeDouble), context->DoubleTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeDoubleComplex), context->DoubleComplexTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeFloat), context->FloatTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeFloatComplex), context->FloatComplexTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeHalf), context->HalfTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeInt), context->IntTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeInt128), context->Int128Ty)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeLong), context->LongTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeLongDouble), context->LongDoubleTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex), context->LongDoubleComplexTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeLongLong), context->LongLongTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeNullPtr), context->NullPtrTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeObjCClass), context->getObjCClassType())); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeObjCID), context->getObjCIdType())); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeObjCSel), context->getObjCSelType())); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeShort), context->ShortTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeSignedChar), context->SignedCharTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedChar), context->UnsignedCharTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedInt), context->UnsignedIntTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedInt128), context->UnsignedInt128Ty)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedLong), context->UnsignedLongTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedLongLong), context->UnsignedLongLongTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeUnsignedShort), context->UnsignedShortTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeVoid), context->VoidTy)); + EXPECT_TRUE(context->hasSameType(GetBasicQualType(eBasicTypeWChar), context->WCharTy)); +} + +TEST_F(TestClangASTContext, TestGetBasicTypeFromName) +{ + EXPECT_EQ(GetBasicQualType(eBasicTypeChar), GetBasicQualType("char")); + EXPECT_EQ(GetBasicQualType(eBasicTypeSignedChar), GetBasicQualType("signed char")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedChar), GetBasicQualType("unsigned char")); + EXPECT_EQ(GetBasicQualType(eBasicTypeWChar), GetBasicQualType("wchar_t")); + EXPECT_EQ(GetBasicQualType(eBasicTypeSignedWChar), GetBasicQualType("signed wchar_t")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedWChar), GetBasicQualType("unsigned wchar_t")); + EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short")); + EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort), GetBasicQualType("unsigned short")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort), GetBasicQualType("unsigned short int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("signed int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt), GetBasicQualType("unsigned int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt), GetBasicQualType("unsigned")); + EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long")); + EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong), GetBasicQualType("unsigned long")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong), GetBasicQualType("unsigned long int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong), GetBasicQualType("long long")); + EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong), GetBasicQualType("long long int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong), GetBasicQualType("unsigned long long")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong), GetBasicQualType("unsigned long long int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeInt128), GetBasicQualType("__int128_t")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128), GetBasicQualType("__uint128_t")); + EXPECT_EQ(GetBasicQualType(eBasicTypeVoid), GetBasicQualType("void")); + EXPECT_EQ(GetBasicQualType(eBasicTypeBool), GetBasicQualType("bool")); + EXPECT_EQ(GetBasicQualType(eBasicTypeFloat), GetBasicQualType("float")); + EXPECT_EQ(GetBasicQualType(eBasicTypeDouble), GetBasicQualType("double")); + EXPECT_EQ(GetBasicQualType(eBasicTypeLongDouble), GetBasicQualType("long double")); + EXPECT_EQ(GetBasicQualType(eBasicTypeObjCID), GetBasicQualType("id")); + EXPECT_EQ(GetBasicQualType(eBasicTypeObjCSel), GetBasicQualType("SEL")); + EXPECT_EQ(GetBasicQualType(eBasicTypeNullPtr), GetBasicQualType("nullptr")); +} + +void +VerifyEncodingAndBitSize(clang::ASTContext *context, lldb::Encoding encoding, int bit_size) +{ + CompilerType type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(context, encoding, bit_size); + EXPECT_TRUE(type.IsValid()); + + QualType qtype = ClangUtil::GetQualType(type); + EXPECT_FALSE(qtype.isNull()); + if (qtype.isNull()) + return; + + uint64_t actual_size = context->getTypeSize(qtype); + EXPECT_EQ(bit_size, actual_size); + + const clang::Type *type_ptr = qtype.getTypePtr(); + EXPECT_NE(nullptr, type_ptr); + if (!type_ptr) + return; + + EXPECT_TRUE(type_ptr->isBuiltinType()); + if (encoding == eEncodingSint) + EXPECT_TRUE(type_ptr->isSignedIntegerType()); + else if (encoding == eEncodingUint) + EXPECT_TRUE(type_ptr->isUnsignedIntegerType()); + else if (encoding == eEncodingIEEE754) + EXPECT_TRUE(type_ptr->isFloatingType()); +} + +TEST_F(TestClangASTContext, TestBuiltinTypeForEncodingAndBitSize) +{ + clang::ASTContext *context = m_ast->getASTContext(); + + // Make sure we can get types of every possible size in every possible encoding. + // We can't make any guarantee about which specific type we get, because the standard + // isn't that specific. We only need to make sure the compiler hands us some type that + // is both a builtin type and matches the requested bit size. + VerifyEncodingAndBitSize(context, eEncodingSint, 8); + VerifyEncodingAndBitSize(context, eEncodingSint, 16); + VerifyEncodingAndBitSize(context, eEncodingSint, 32); + VerifyEncodingAndBitSize(context, eEncodingSint, 64); + VerifyEncodingAndBitSize(context, eEncodingSint, 128); + + VerifyEncodingAndBitSize(context, eEncodingUint, 8); + VerifyEncodingAndBitSize(context, eEncodingUint, 16); + VerifyEncodingAndBitSize(context, eEncodingUint, 32); + VerifyEncodingAndBitSize(context, eEncodingUint, 64); + VerifyEncodingAndBitSize(context, eEncodingUint, 128); + + VerifyEncodingAndBitSize(context, eEncodingIEEE754, 32); + VerifyEncodingAndBitSize(context, eEncodingIEEE754, 64); +} + +TEST_F(TestClangASTContext, TestIsClangType) +{ + clang::ASTContext *context = m_ast->getASTContext(); + lldb::opaque_compiler_type_t bool_ctype = ClangASTContext::GetOpaqueCompilerType(context, lldb::eBasicTypeBool); + CompilerType bool_type(m_ast.get(), bool_ctype); + CompilerType record_type = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct, + lldb::eLanguageTypeC_plus_plus, nullptr); + // Clang builtin type and record type should pass + EXPECT_TRUE(ClangUtil::IsClangType(bool_type)); + EXPECT_TRUE(ClangUtil::IsClangType(record_type)); + + // Default constructed type should fail + EXPECT_FALSE(ClangUtil::IsClangType(CompilerType())); + + // Go type should fail + GoASTContext go_ast; + CompilerType go_type(&go_ast, bool_ctype); + EXPECT_FALSE(ClangUtil::IsClangType(go_type)); +} + +TEST_F(TestClangASTContext, TestRemoveFastQualifiers) +{ + CompilerType record_type = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct, + lldb::eLanguageTypeC_plus_plus, nullptr); + QualType qt; + + qt = ClangUtil::GetQualType(record_type); + EXPECT_EQ(0, qt.getLocalFastQualifiers()); + record_type = record_type.AddConstModifier(); + record_type = record_type.AddVolatileModifier(); + record_type = record_type.AddRestrictModifier(); + qt = ClangUtil::GetQualType(record_type); + EXPECT_NE(0, qt.getLocalFastQualifiers()); + record_type = ClangUtil::RemoveFastQualifiers(record_type); + qt = ClangUtil::GetQualType(record_type); + EXPECT_EQ(0, qt.getLocalFastQualifiers()); +} + +TEST_F(TestClangASTContext, TestConvertAccessTypeToAccessSpecifier) +{ + EXPECT_EQ(AS_none, ClangASTContext::ConvertAccessTypeToAccessSpecifier(eAccessNone)); + EXPECT_EQ(AS_none, ClangASTContext::ConvertAccessTypeToAccessSpecifier(eAccessPackage)); + EXPECT_EQ(AS_public, ClangASTContext::ConvertAccessTypeToAccessSpecifier(eAccessPublic)); + EXPECT_EQ(AS_private, ClangASTContext::ConvertAccessTypeToAccessSpecifier(eAccessPrivate)); + EXPECT_EQ(AS_protected, ClangASTContext::ConvertAccessTypeToAccessSpecifier(eAccessProtected)); +} + +TEST_F(TestClangASTContext, TestUnifyAccessSpecifiers) +{ + // Unifying two of the same type should return the same type + EXPECT_EQ(AS_public, ClangASTContext::UnifyAccessSpecifiers(AS_public, AS_public)); + EXPECT_EQ(AS_private, ClangASTContext::UnifyAccessSpecifiers(AS_private, AS_private)); + EXPECT_EQ(AS_protected, ClangASTContext::UnifyAccessSpecifiers(AS_protected, AS_protected)); + + // Otherwise the result should be the strictest of the two. + EXPECT_EQ(AS_private, ClangASTContext::UnifyAccessSpecifiers(AS_private, AS_public)); + EXPECT_EQ(AS_private, ClangASTContext::UnifyAccessSpecifiers(AS_private, AS_protected)); + EXPECT_EQ(AS_private, ClangASTContext::UnifyAccessSpecifiers(AS_public, AS_private)); + EXPECT_EQ(AS_private, ClangASTContext::UnifyAccessSpecifiers(AS_protected, AS_private)); + EXPECT_EQ(AS_protected, ClangASTContext::UnifyAccessSpecifiers(AS_protected, AS_public)); + EXPECT_EQ(AS_protected, ClangASTContext::UnifyAccessSpecifiers(AS_public, AS_protected)); + + // None is stricter than everything (by convention) + EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_none, AS_public)); + EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_none, AS_protected)); + EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_none, AS_private)); + EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_public, AS_none)); + EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_protected, AS_none)); + EXPECT_EQ(AS_none, ClangASTContext::UnifyAccessSpecifiers(AS_private, AS_none)); +} + +TEST_F(TestClangASTContext, TestRecordHasFields) +{ + CompilerType int_type = ClangASTContext::GetBasicType(m_ast->getASTContext(), eBasicTypeInt); + + // Test that a record with no fields returns false + CompilerType empty_base = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct, + lldb::eLanguageTypeC_plus_plus, nullptr); + ClangASTContext::StartTagDeclarationDefinition(empty_base); + ClangASTContext::CompleteTagDeclarationDefinition(empty_base); + + RecordDecl *empty_base_decl = ClangASTContext::GetAsRecordDecl(empty_base); + EXPECT_NE(nullptr, empty_base_decl); + EXPECT_FALSE(ClangASTContext::RecordHasFields(empty_base_decl)); + + // Test that a record with direct fields returns true + CompilerType non_empty_base = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "NonEmptyBase", + clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); + ClangASTContext::StartTagDeclarationDefinition(non_empty_base); + FieldDecl *non_empty_base_field_decl = + m_ast->AddFieldToRecordType(non_empty_base, "MyField", int_type, eAccessPublic, 0); + ClangASTContext::CompleteTagDeclarationDefinition(non_empty_base); + RecordDecl *non_empty_base_decl = ClangASTContext::GetAsRecordDecl(non_empty_base); + EXPECT_NE(nullptr, non_empty_base_decl); + EXPECT_NE(nullptr, non_empty_base_field_decl); + EXPECT_TRUE(ClangASTContext::RecordHasFields(non_empty_base_decl)); + + // Test that a record with no direct fields, but fields in a base returns true + CompilerType empty_derived = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "EmptyDerived", + clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); + ClangASTContext::StartTagDeclarationDefinition(empty_derived); + CXXBaseSpecifier *non_empty_base_spec = + m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(), lldb::eAccessPublic, false, false); + bool result = m_ast->SetBaseClassesForClassType(empty_derived.GetOpaqueQualType(), &non_empty_base_spec, 1); + ClangASTContext::CompleteTagDeclarationDefinition(empty_derived); + EXPECT_TRUE(result); + CXXRecordDecl *empty_derived_non_empty_base_cxx_decl = m_ast->GetAsCXXRecordDecl(empty_derived.GetOpaqueQualType()); + RecordDecl *empty_derived_non_empty_base_decl = ClangASTContext::GetAsRecordDecl(empty_derived); + EXPECT_EQ(1, ClangASTContext::GetNumBaseClasses(empty_derived_non_empty_base_cxx_decl, false)); + EXPECT_TRUE(ClangASTContext::RecordHasFields(empty_derived_non_empty_base_decl)); + + // Test that a record with no direct fields, but fields in a virtual base returns true + CompilerType empty_derived2 = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "EmptyDerived2", + clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); + ClangASTContext::StartTagDeclarationDefinition(empty_derived2); + CXXBaseSpecifier *non_empty_vbase_spec = + m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(), lldb::eAccessPublic, true, false); + result = m_ast->SetBaseClassesForClassType(empty_derived2.GetOpaqueQualType(), &non_empty_vbase_spec, 1); + ClangASTContext::CompleteTagDeclarationDefinition(empty_derived2); + EXPECT_TRUE(result); + CXXRecordDecl *empty_derived_non_empty_vbase_cxx_decl = + m_ast->GetAsCXXRecordDecl(empty_derived2.GetOpaqueQualType()); + RecordDecl *empty_derived_non_empty_vbase_decl = ClangASTContext::GetAsRecordDecl(empty_derived2); + EXPECT_EQ(1, ClangASTContext::GetNumBaseClasses(empty_derived_non_empty_vbase_cxx_decl, false)); + EXPECT_TRUE(ClangASTContext::RecordHasFields(empty_derived_non_empty_vbase_decl)); +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits