<commit_before>//===--- Type.cpp - Type representation and manipulation ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements type-related functionality.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/AST/Type.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "llvm/ADT/StringExtras.h"

using namespace clang;

bool QualType::isConstant(ASTContext& Ctx) const {
  if (isConstQualified())
    return true;

  if (getTypePtr()->isArrayType())
    return Ctx.getAsArrayType(*this)->getElementType().isConstant(Ctx);

  return false;
}

void Type::Destroy(ASTContext& C) { delete this; }

void FunctionTypeProto::Destroy(ASTContext& C) {
  // Destroy the object, but don't call delete.  These are malloc'd.
  this->~FunctionTypeProto();
  free(this);  
}

void VariableArrayType::Destroy(ASTContext& C) {
  SizeExpr->Destroy(C);
  delete this;  
}

void DependentSizedArrayType::Destroy(ASTContext& C) {
  SizeExpr->Destroy(C);
  delete this;
}

/// getArrayElementTypeNoTypeQual - If this is an array type, return the
/// element type of the array, potentially with type qualifiers missing.
/// This method should never be used when type qualifiers are meaningful.
const Type *Type::getArrayElementTypeNoTypeQual() const {
  // If this is directly an array type, return it.
  if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
    return ATy->getElementType().getTypePtr();
    
  // If the canonical form of this type isn't the right kind, reject it.
  if (!isa<ArrayType>(CanonicalType)) {
    // Look through type qualifiers
    if (ArrayType *AT = dyn_cast<ArrayType>(CanonicalType.getUnqualifiedType()))
      return AT->getElementType().getTypePtr();
    return 0;
  }
  
  // If this is a typedef for an array type, strip the typedef off without
  // losing all typedef information.
  return getDesugaredType()->getArrayElementTypeNoTypeQual();
}

/// getDesugaredType - Return the specified type with any "sugar" removed from
/// type type.  This takes off typedefs, typeof's etc.  If the outer level of
/// the type is already concrete, it returns it unmodified.  This is similar
/// to getting the canonical type, but it doesn't remove *all* typedefs.  For
/// example, it return "T*" as "T*", (not as "int*"), because the pointer is
/// concrete.
QualType Type::getDesugaredType() const {
  if (const TypedefType *TDT = dyn_cast<TypedefType>(this))
    return TDT->LookThroughTypedefs();
  if (const TypeOfExpr *TOE = dyn_cast<TypeOfExpr>(this))
    return TOE->getUnderlyingExpr()->getType();
  if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this))
    return TOT->getUnderlyingType();
  // FIXME: remove this cast.
  return QualType(const_cast<Type*>(this), 0);
}

/// isVoidType - Helper method to determine if this is the 'void' type.
bool Type::isVoidType() const {
  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
    return BT->getKind() == BuiltinType::Void;
  return false;
}

bool Type::isObjectType() const {
  if (isa<FunctionType>(CanonicalType))
    return false;
  else if (CanonicalType->isIncompleteType())
    return false;
  else
    return true;
}

bool Type::isDerivedType() const {
  switch (CanonicalType->getTypeClass()) {
  case Pointer:
  case VariableArray:
  case ConstantArray:
  case IncompleteArray:
  case FunctionProto:
  case FunctionNoProto:
  case Reference:
    return true;
  case Tagged: {
    const TagType *TT = cast<TagType>(CanonicalType);
    return !TT->getDecl()->isEnum();
  }
  default:
    return false;
  }
}

bool Type::isClassType() const {
  if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType))
    if (RT->getDecl()->isClass())
      return true;
  return false;
}
bool Type::isStructureType() const {
  if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType))
    if (RT->getDecl()->isStruct())
      return true;
  return false;
}
bool Type::isUnionType() const {
  if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType))
    if (RT->getDecl()->isUnion())
      return true;
  return false;
}

bool Type::isComplexType() const {
  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
    return CT->getElementType()->isFloatingType();
  return false;
}

bool Type::isComplexIntegerType() const {
  // Check for GCC complex integer extension.
  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
    return CT->getElementType()->isIntegerType();
  return false;
}

const ComplexType *Type::getAsComplexIntegerType() const {
  // Are we directly a complex type?
  if (const ComplexType *CTy = dyn_cast<ComplexType>(this)) {
    if (CTy->getElementType()->isIntegerType())
      return CTy;
  }
  // If the canonical form of this type isn't the right kind, reject it.
  const ComplexType *CTy = dyn_cast<ComplexType>(CanonicalType);
  if (!CTy || !CTy->getElementType()->isIntegerType())
    return 0;<commit_msg>simplify these predicates a bit.<commit_after>//===--- Type.cpp - Type representation and manipulation ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements type-related functionality.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/AST/Type.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "llvm/ADT/StringExtras.h"

using namespace clang;

bool QualType::isConstant(ASTContext& Ctx) const {
  if (isConstQualified())
    return true;

  if (getTypePtr()->isArrayType())
    return Ctx.getAsArrayType(*this)->getElementType().isConstant(Ctx);

  return false;
}

void Type::Destroy(ASTContext& C) { delete this; }

void FunctionTypeProto::Destroy(ASTContext& C) {
  // Destroy the object, but don't call delete.  These are malloc'd.
  this->~FunctionTypeProto();
  free(this);  
}

void VariableArrayType::Destroy(ASTContext& C) {
  SizeExpr->Destroy(C);
  delete this;  
}

void DependentSizedArrayType::Destroy(ASTContext& C) {
  SizeExpr->Destroy(C);
  delete this;
}

/// getArrayElementTypeNoTypeQual - If this is an array type, return the
/// element type of the array, potentially with type qualifiers missing.
/// This method should never be used when type qualifiers are meaningful.
const Type *Type::getArrayElementTypeNoTypeQual() const {
  // If this is directly an array type, return it.
  if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
    return ATy->getElementType().getTypePtr();
    
  // If the canonical form of this type isn't the right kind, reject it.
  if (!isa<ArrayType>(CanonicalType)) {
    // Look through type qualifiers
    if (ArrayType *AT = dyn_cast<ArrayType>(CanonicalType.getUnqualifiedType()))
      return AT->getElementType().getTypePtr();
    return 0;
  }
  
  // If this is a typedef for an array type, strip the typedef off without
  // losing all typedef information.
  return getDesugaredType()->getArrayElementTypeNoTypeQual();
}

/// getDesugaredType - Return the specified type with any "sugar" removed from
/// type type.  This takes off typedefs, typeof's etc.  If the outer level of
/// the type is already concrete, it returns it unmodified.  This is similar
/// to getting the canonical type, but it doesn't remove *all* typedefs.  For
/// example, it return "T*" as "T*", (not as "int*"), because the pointer is
/// concrete.
QualType Type::getDesugaredType() const {
  if (const TypedefType *TDT = dyn_cast<TypedefType>(this))
    return TDT->LookThroughTypedefs();
  if (const TypeOfExpr *TOE = dyn_cast<TypeOfExpr>(this))
    return TOE->getUnderlyingExpr()->getType();
  if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this))
    return TOT->getUnderlyingType();
  // FIXME: remove this cast.
  return QualType(const_cast<Type*>(this), 0);
}

/// isVoidType - Helper method to determine if this is the 'void' type.
bool Type::isVoidType() const {
  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
    return BT->getKind() == BuiltinType::Void;
  return false;
}

bool Type::isObjectType() const {
  if (isa<FunctionType>(CanonicalType))
    return false;
  else if (CanonicalType->isIncompleteType())
    return false;
  else
    return true;
}

bool Type::isDerivedType() const {
  switch (CanonicalType->getTypeClass()) {
  case Pointer:
  case VariableArray:
  case ConstantArray:
  case IncompleteArray:
  case FunctionProto:
  case FunctionNoProto:
  case Reference:
    return true;
  case Tagged: {
    const TagType *TT = cast<TagType>(CanonicalType);
    return !TT->getDecl()->isEnum();
  }
  default:
    return false;
  }
}

bool Type::isClassType() const {
  if (const RecordType *RT = getAsRecordType())
    return RT->getDecl()->isClass();
  return false;
}
bool Type::isStructureType() const {
  if (const RecordType *RT = getAsRecordType())
    return RT->getDecl()->isStruct();
  return false;
}
bool Type::isUnionType() const {
  if (const RecordType *RT = getAsRecordType())
    return RT->getDecl()->isUnion();
  return false;
}

bool Type::isComplexType() const {
  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
    return CT->getElementType()->isFloatingType();
  return false;
}

bool Type::isComplexIntegerType() const {
  // Check for GCC complex integer extension.
  if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
    return CT->getElementType()->isIntegerType();
  return false;
}

const ComplexType *Type::getAsComplexIntegerType() const {
  // Are we directly a complex type?
  if (const ComplexType *CTy = dyn_cast<ComplexType>(this)) {
    if (CTy->getElementType()->isIntegerType())
      return CTy;
  }
  // If the canonical form of this type isn't the right kind, reject it.
  const ComplexType *CTy = dyn_cast<ComplexType>(CanonicalType);
  if (!CTy || !CTy->getElementType()->isIntegerType())
    return 0;
{'fraction_non_alphanumeric': 0.15769267684038776, 'fraction_numerical': 0.0005758710048949035, 'mean_word_length': 3.4797936371453138, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7010256', 'n_tokens_mistral': 3128, 'n_tokens_neox': 3101, 'n_words': 927}