Пример #1
0
bool 
CXXConstructorDecl::isCopyConstructor(ASTContext &Context, 
                                      unsigned &TypeQuals) const {
  // C++ [class.copy]p2:
  //   A non-template constructor for class X is a copy constructor
  //   if its first parameter is of type X&, const X&, volatile X& or
  //   const volatile X&, and either there are no other parameters
  //   or else all other parameters have default arguments (8.3.6).
  if ((getNumParams() < 1) ||
      (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() == 0))
    return false;

  const ParmVarDecl *Param = getParamDecl(0);

  // Do we have a reference type? Rvalue references don't count.
  const LValueReferenceType *ParamRefType =
    Param->getType()->getAsLValueReferenceType();
  if (!ParamRefType)
    return false;

  // Is it a reference to our class type?
  QualType PointeeType 
    = Context.getCanonicalType(ParamRefType->getPointeeType());
  QualType ClassTy 
    = Context.getTagDeclType(const_cast<CXXRecordDecl*>(getParent()));
  if (PointeeType.getUnqualifiedType() != ClassTy)
    return false;

  // We have a copy constructor.
  TypeQuals = PointeeType.getCVRQualifiers();
  return true;
}
Пример #2
0
DeclarationName 
DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 
                                        QualType Ty) {
  assert(Kind >= DeclarationName::CXXConstructorName &&
         Kind <= DeclarationName::CXXConversionFunctionName &&
         "Kind must be a C++ special name kind");
  
  llvm::FoldingSet<CXXSpecialName> *SpecialNames 
    = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);

  DeclarationNameExtra::ExtraKind EKind;
  switch (Kind) {
  case DeclarationName::CXXConstructorName: 
    EKind = DeclarationNameExtra::CXXConstructor;
    assert(Ty.getCVRQualifiers() == 0 &&"Constructor type must be unqualified");
    break;
  case DeclarationName::CXXDestructorName:
    EKind = DeclarationNameExtra::CXXDestructor;
    assert(Ty.getCVRQualifiers() == 0 && "Destructor type must be unqualified");
    break;
  case DeclarationName::CXXConversionFunctionName:
    EKind = DeclarationNameExtra::CXXConversionFunction;
    break;
  default:
    return DeclarationName();
  }

  // Unique selector, to guarantee there is one per name.
  llvm::FoldingSetNodeID ID;
  ID.AddInteger(EKind);
  ID.AddPointer(Ty.getAsOpaquePtr());

  void *InsertPos = 0;
  if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
    return DeclarationName(Name);

  CXXSpecialName *SpecialName = new CXXSpecialName;
  SpecialName->ExtraKindOrNumArgs = EKind;
  SpecialName->Type = Ty;
  SpecialName->FETokenInfo = 0;

  SpecialNames->InsertNode(SpecialName, InsertPos);
  return DeclarationName(SpecialName);
}
Пример #3
0
/// CastsAwayConstness - Check if the pointer conversion from SrcType to
/// DestType casts away constness as defined in C++ 5.2.11p8ff. This is used by
/// the cast checkers.  Both arguments must denote pointer (possibly to member)
/// types.
bool
CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType)
{
  // Casting away constness is defined in C++ 5.2.11p8 with reference to
  // C++ 4.4. We piggyback on Sema::IsQualificationConversion for this, since
  // the rules are non-trivial. So first we construct Tcv *...cv* as described
  // in C++ 5.2.11p8.
  assert((SrcType->isPointerType() || SrcType->isMemberPointerType()) &&
         "Source type is not pointer or pointer to member.");
  assert((DestType->isPointerType() || DestType->isMemberPointerType()) &&
         "Destination type is not pointer or pointer to member.");

  QualType UnwrappedSrcType = SrcType, UnwrappedDestType = DestType;
  llvm::SmallVector<unsigned, 8> cv1, cv2;

  // Find the qualifications.
  while (Self.UnwrapSimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) {
    cv1.push_back(UnwrappedSrcType.getCVRQualifiers());
    cv2.push_back(UnwrappedDestType.getCVRQualifiers());
  }
  assert(cv1.size() > 0 && "Must have at least one pointer level.");

  // Construct void pointers with those qualifiers (in reverse order of
  // unwrapping, of course).
  QualType SrcConstruct = Self.Context.VoidTy;
  QualType DestConstruct = Self.Context.VoidTy;
  for (llvm::SmallVector<unsigned, 8>::reverse_iterator i1 = cv1.rbegin(),
                                                        i2 = cv2.rbegin();
       i1 != cv1.rend(); ++i1, ++i2)
  {
    SrcConstruct = Self.Context.getPointerType(
      SrcConstruct.getQualifiedType(*i1));
    DestConstruct = Self.Context.getPointerType(
      DestConstruct.getQualifiedType(*i2));
  }

  // Test if they're compatible.
  return SrcConstruct != DestConstruct &&
    !Self.IsQualificationConversion(SrcConstruct, DestConstruct);
}
Пример #4
0
/// getOrCreateType - Get the type from the cache or create a new
/// one if necessary.
llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
                                          llvm::DICompileUnit Unit) {
  if (Ty.isNull())
    return llvm::DIType();
  
  // Check to see if the compile unit already has created this type.
  llvm::DIType &Slot = TypeCache[Ty.getAsOpaquePtr()];
  if (!Slot.isNull()) return Slot;

  // Handle CVR qualifiers, which recursively handles what they refer to.
  if (Ty.getCVRQualifiers())
    return Slot = CreateCVRType(Ty, Unit);

  // Work out details of type.
  switch (Ty->getTypeClass()) {
#define TYPE(Class, Base)
#define ABSTRACT_TYPE(Class, Base)
#define NON_CANONICAL_TYPE(Class, Base)
#define DEPENDENT_TYPE(Class, Base) case Type::Class:
#include "clang/AST/TypeNodes.def"
    assert(false && "Dependent types cannot show up in debug information");
    
  case Type::Complex:
  case Type::LValueReference:
  case Type::RValueReference:
  case Type::Vector:
  case Type::ExtVector:
  case Type::ExtQual:
  case Type::ObjCQualifiedInterface:
  case Type::ObjCQualifiedId:
  case Type::FixedWidthInt:
  case Type::BlockPointer:
  case Type::MemberPointer:
  case Type::TemplateSpecialization:
  case Type::QualifiedName:
  case Type::ObjCQualifiedClass:
    // Unsupported types
    return llvm::DIType();

  case Type::ObjCInterface: 
    Slot = CreateType(cast<ObjCInterfaceType>(Ty), Unit); break;
  case Type::Builtin: Slot = CreateType(cast<BuiltinType>(Ty), Unit); break;
  case Type::Pointer: Slot = CreateType(cast<PointerType>(Ty), Unit); break;
  case Type::Typedef: Slot = CreateType(cast<TypedefType>(Ty), Unit); break;
  case Type::Record:
  case Type::Enum:
    Slot = CreateType(cast<TagType>(Ty), Unit); 
    break;
  case Type::FunctionProto:
  case Type::FunctionNoProto:
    return Slot = CreateType(cast<FunctionType>(Ty), Unit);
    
  case Type::ConstantArray:
  case Type::VariableArray:
  case Type::IncompleteArray:
    return Slot = CreateType(cast<ArrayType>(Ty), Unit);
  case Type::TypeOfExpr:
    return Slot = getOrCreateType(cast<TypeOfExprType>(Ty)->getUnderlyingExpr()
                                  ->getType(), Unit);
  case Type::TypeOf:
    return Slot = getOrCreateType(cast<TypeOfType>(Ty)->getUnderlyingType(),
                                  Unit);
  }
  
  return Slot;
}
Пример #5
0
/// GetTypeForDeclarator - Convert the type for the specified
/// declarator to Type instances. Skip the outermost Skip type
/// objects.
QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
  bool OmittedReturnType = false;

  if (D.getContext() == Declarator::BlockLiteralContext
      && Skip == 0
      && !D.getDeclSpec().hasTypeSpecifier()
      && (D.getNumTypeObjects() == 0
          || (D.getNumTypeObjects() == 1
              && D.getTypeObject(0).Kind == DeclaratorChunk::Function)))
    OmittedReturnType = true;

  // long long is a C99 feature.
  if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x &&
      D.getDeclSpec().getTypeSpecWidth() == DeclSpec::TSW_longlong)
    Diag(D.getDeclSpec().getTypeSpecWidthLoc(), diag::ext_longlong);

  // Determine the type of the declarator. Not all forms of declarator
  // have a type.
  QualType T;
  switch (D.getKind()) {
  case Declarator::DK_Abstract:
  case Declarator::DK_Normal:
  case Declarator::DK_Operator: {
    const DeclSpec& DS = D.getDeclSpec();
    if (OmittedReturnType)
      // We default to a dependent type initially.  Can be modified by
      // the first return statement.
      T = Context.DependentTy;
    else {
      T = ConvertDeclSpecToType(DS);
      if (T.isNull())
        return T;
    }
    break;
  }

  case Declarator::DK_Constructor:
  case Declarator::DK_Destructor:
  case Declarator::DK_Conversion:
    // Constructors and destructors don't have return types. Use
    // "void" instead. Conversion operators will check their return
    // types separately.
    T = Context.VoidTy;
    break;
  }

  // The name we're declaring, if any.
  DeclarationName Name;
  if (D.getIdentifier())
    Name = D.getIdentifier();

  // Walk the DeclTypeInfo, building the recursive type as we go.
  // DeclTypeInfos are ordered from the identifier out, which is
  // opposite of what we want :).
  for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) {
    DeclaratorChunk &DeclType = D.getTypeObject(e-i-1+Skip);
    switch (DeclType.Kind) {
    default: assert(0 && "Unknown decltype!");
    case DeclaratorChunk::BlockPointer:
      // If blocks are disabled, emit an error.
      if (!LangOpts.Blocks)
        Diag(DeclType.Loc, diag::err_blocks_disable);
        
      if (DeclType.Cls.TypeQuals)
        Diag(D.getIdentifierLoc(), diag::err_qualified_block_pointer_type);
      if (!T.getTypePtr()->isFunctionType())
        Diag(D.getIdentifierLoc(), diag::err_nonfunction_block_type);
      else
        T = Context.getBlockPointerType(T);
      break;
    case DeclaratorChunk::Pointer:
      T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name);
      break;
    case DeclaratorChunk::Reference:
      T = BuildReferenceType(T, DeclType.Ref.LValueRef,
                             DeclType.Ref.HasRestrict ? QualType::Restrict : 0,
                             DeclType.Loc, Name);
      break;
    case DeclaratorChunk::Array: {
      DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
      Expr *ArraySize = static_cast<Expr*>(ATI.NumElts);
      ArrayType::ArraySizeModifier ASM;
      if (ATI.isStar)
        ASM = ArrayType::Star;
      else if (ATI.hasStatic)
        ASM = ArrayType::Static;
      else
        ASM = ArrayType::Normal;
      T = BuildArrayType(T, ASM, ArraySize, ATI.TypeQuals, DeclType.Loc, Name);
      break;
    }
    case DeclaratorChunk::Function: {
      // If the function declarator has a prototype (i.e. it is not () and
      // does not have a K&R-style identifier list), then the arguments are part
      // of the type, otherwise the argument list is ().
      const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
      
      // C99 6.7.5.3p1: The return type may not be a function or array type.
      if (T->isArrayType() || T->isFunctionType()) {
        Diag(DeclType.Loc, diag::err_func_returning_array_function) << T;
        T = Context.IntTy;
        D.setInvalidType(true);
      }
        
      if (FTI.NumArgs == 0) {
        if (getLangOptions().CPlusPlus) {
          // C++ 8.3.5p2: If the parameter-declaration-clause is empty, the
          // function takes no arguments.
          T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic,FTI.TypeQuals);
        } else if (FTI.isVariadic) {
          // We allow a zero-parameter variadic function in C if the
          // function is marked with the "overloadable"
          // attribute. Scan for this attribute now.
          bool Overloadable = false;
          for (const AttributeList *Attrs = D.getAttributes();
               Attrs; Attrs = Attrs->getNext()) {
            if (Attrs->getKind() == AttributeList::AT_overloadable) {
              Overloadable = true;
              break;
            }
          }

          if (!Overloadable)
            Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg);
          T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, 0);
        } else {
          // Simple void foo(), where the incoming T is the result type.
          T = Context.getFunctionNoProtoType(T);
        }
      } else if (FTI.ArgInfo[0].Param == 0) {
        // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
        Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);        
      } else {
        // Otherwise, we have a function with an argument list that is
        // potentially variadic.
        llvm::SmallVector<QualType, 16> ArgTys;
        
        for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
          ParmVarDecl *Param =
            cast<ParmVarDecl>(FTI.ArgInfo[i].Param.getAs<Decl>());
          QualType ArgTy = Param->getType();
          assert(!ArgTy.isNull() && "Couldn't parse type?");

          // Adjust the parameter type.
          assert((ArgTy == adjustParameterType(ArgTy)) && "Unadjusted type?");

          // Look for 'void'.  void is allowed only as a single argument to a
          // function with no other parameters (C99 6.7.5.3p10).  We record
          // int(void) as a FunctionProtoType with an empty argument list.
          if (ArgTy->isVoidType()) {
            // If this is something like 'float(int, void)', reject it.  'void'
            // is an incomplete type (C99 6.2.5p19) and function decls cannot
            // have arguments of incomplete type.
            if (FTI.NumArgs != 1 || FTI.isVariadic) {
              Diag(DeclType.Loc, diag::err_void_only_param);
              ArgTy = Context.IntTy;
              Param->setType(ArgTy);
            } else if (FTI.ArgInfo[i].Ident) {
              // Reject, but continue to parse 'int(void abc)'.
              Diag(FTI.ArgInfo[i].IdentLoc,
                   diag::err_param_with_void_type);
              ArgTy = Context.IntTy;
              Param->setType(ArgTy);
            } else {
              // Reject, but continue to parse 'float(const void)'.
              if (ArgTy.getCVRQualifiers())
                Diag(DeclType.Loc, diag::err_void_param_qualified);
              
              // Do not add 'void' to the ArgTys list.
              break;
            }
          } else if (!FTI.hasPrototype) {
            if (ArgTy->isPromotableIntegerType()) {
              ArgTy = Context.IntTy;
            } else if (const BuiltinType* BTy = ArgTy->getAsBuiltinType()) {
              if (BTy->getKind() == BuiltinType::Float)
                ArgTy = Context.DoubleTy;
            }
          }
          
          ArgTys.push_back(ArgTy);
        }
        T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
                                    FTI.isVariadic, FTI.TypeQuals);
      }
      break;
    }
    case DeclaratorChunk::MemberPointer:
      // The scope spec must refer to a class, or be dependent.
      DeclContext *DC = computeDeclContext(DeclType.Mem.Scope());
      QualType ClsType;
      // FIXME: Extend for dependent types when it's actually supported.
      // See ActOnCXXNestedNameSpecifier.
      if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(DC)) {
        ClsType = Context.getTagDeclType(RD);
      } else {
        if (DC) {
          Diag(DeclType.Mem.Scope().getBeginLoc(),
               diag::err_illegal_decl_mempointer_in_nonclass)
            << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name")
            << DeclType.Mem.Scope().getRange();
        }
        D.setInvalidType(true);
        ClsType = Context.IntTy;
      }

      // C++ 8.3.3p3: A pointer to member shall not pointer to ... a member
      //   with reference type, or "cv void."
      if (T->isReferenceType()) {
        Diag(DeclType.Loc, diag::err_illegal_decl_pointer_to_reference)
          << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
        D.setInvalidType(true);
        T = Context.IntTy;
      }
      if (T->isVoidType()) {
        Diag(DeclType.Loc, diag::err_illegal_decl_mempointer_to_void)
          << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
        T = Context.IntTy;
      }

      // Enforce C99 6.7.3p2: "Types other than pointer types derived from
      // object or incomplete types shall not be restrict-qualified."
      if ((DeclType.Mem.TypeQuals & QualType::Restrict) &&
          !T->isIncompleteOrObjectType()) {
        Diag(DeclType.Loc, diag::err_typecheck_invalid_restrict_invalid_pointee)
          << T;
        DeclType.Mem.TypeQuals &= ~QualType::Restrict;
      }

      T = Context.getMemberPointerType(T, ClsType.getTypePtr()).
                    getQualifiedType(DeclType.Mem.TypeQuals);

      break;
    }

    if (T.isNull()) {
      D.setInvalidType(true);
      T = Context.IntTy;
    }

    // See if there are any attributes on this declarator chunk.
    if (const AttributeList *AL = DeclType.getAttrs())
      ProcessTypeAttributeList(T, AL);
  }

  if (getLangOptions().CPlusPlus && T->isFunctionType()) {
    const FunctionProtoType *FnTy = T->getAsFunctionProtoType();
    assert(FnTy && "Why oh why is there not a FunctionProtoType here ?");

    // C++ 8.3.5p4: A cv-qualifier-seq shall only be part of the function type
    // for a nonstatic member function, the function type to which a pointer
    // to member refers, or the top-level function type of a function typedef
    // declaration.
    if (FnTy->getTypeQuals() != 0 &&
        D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
        ((D.getContext() != Declarator::MemberContext &&
          (!D.getCXXScopeSpec().isSet() ||
           !computeDeclContext(D.getCXXScopeSpec())->isRecord())) ||
         D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)) {
      if (D.isFunctionDeclarator())
        Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_function_type);
      else
        Diag(D.getIdentifierLoc(),
             diag::err_invalid_qualified_typedef_function_type_use);

      // Strip the cv-quals from the type.
      T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(),
                                  FnTy->getNumArgs(), FnTy->isVariadic(), 0);
    }
  }
  
  // If there were any type attributes applied to the decl itself (not the
  // type, apply the type attribute to the type!)
  if (const AttributeList *Attrs = D.getAttributes())
    ProcessTypeAttributeList(T, Attrs);
  
  return T;
}
Пример #6
0
/// \brief Build a reference type.
///
/// \param T The type to which we'll be building a reference.
///
/// \param Quals The cvr-qualifiers to be applied to the reference type.
///
/// \param Loc The location of the entity whose type involves this
/// reference type or, if there is no such entity, the location of the
/// type that will have reference type.
///
/// \param Entity The name of the entity that involves the reference
/// type, if known.
///
/// \returns A suitable reference type, if there are no
/// errors. Otherwise, returns a NULL type.
QualType Sema::BuildReferenceType(QualType T, bool LValueRef, unsigned Quals,
                                  SourceLocation Loc, DeclarationName Entity) {
  if (LValueRef) {
    if (const RValueReferenceType *R = T->getAsRValueReferenceType()) {
      // C++0x [dcl.typedef]p9: If a typedef TD names a type that is a
      //   reference to a type T, and attempt to create the type "lvalue
      //   reference to cv TD" creates the type "lvalue reference to T".
      // We use the qualifiers (restrict or none) of the original reference,
      // not the new ones. This is consistent with GCC.
      return Context.getLValueReferenceType(R->getPointeeType()).
               getQualifiedType(T.getCVRQualifiers());
    }
  }
  if (T->isReferenceType()) {
    // C++ [dcl.ref]p4: There shall be no references to references.
    // 
    // According to C++ DR 106, references to references are only
    // diagnosed when they are written directly (e.g., "int & &"),
    // but not when they happen via a typedef:
    //
    //   typedef int& intref;
    //   typedef intref& intref2;
    //
    // Parser::ParserDeclaratorInternal diagnoses the case where
    // references are written directly; here, we handle the
    // collapsing of references-to-references as described in C++
    // DR 106 and amended by C++ DR 540.
    return T;
  }

  // C++ [dcl.ref]p1:
  //   A declarator that specifies the type “reference to cv void”
  //   is ill-formed.
  if (T->isVoidType()) {
    Diag(Loc, diag::err_reference_to_void);
    return QualType();
  }

  // Enforce C99 6.7.3p2: "Types other than pointer types derived from
  // object or incomplete types shall not be restrict-qualified."
  if ((Quals & QualType::Restrict) && !T->isIncompleteOrObjectType()) {
    Diag(Loc, diag::err_typecheck_invalid_restrict_invalid_pointee)
      << T;
    Quals &= ~QualType::Restrict;
  }

  // C++ [dcl.ref]p1:
  //   [...] Cv-qualified references are ill-formed except when the
  //   cv-qualifiers are introduced through the use of a typedef
  //   (7.1.3) or of a template type argument (14.3), in which case
  //   the cv-qualifiers are ignored.
  //
  // We diagnose extraneous cv-qualifiers for the non-typedef,
  // non-template type argument case within the parser. Here, we just
  // ignore any extraneous cv-qualifiers.
  Quals &= ~QualType::Const;
  Quals &= ~QualType::Volatile;

  // Handle restrict on references.
  if (LValueRef)
    return Context.getLValueReferenceType(T).getQualifiedType(Quals);
  return Context.getRValueReferenceType(T).getQualifiedType(Quals);
}