diff options
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r-- | lib/Sema/SemaType.cpp | 176 |
1 files changed, 110 insertions, 66 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 54f8dba..4b23167 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -105,7 +105,8 @@ static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr, case AttributeList::AT_ThisCall: \ case AttributeList::AT_Pascal: \ case AttributeList::AT_Regparm: \ - case AttributeList::AT_Pcs \ + case AttributeList::AT_Pcs: \ + case AttributeList::AT_PnaclCall \ namespace { /// An object which stores processing state for the entire @@ -552,19 +553,28 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state, SourceLocation loc = declarator.getLocStart(); // ...and *prepend* it to the declarator. + SourceLocation NoLoc; declarator.AddInnermostTypeInfo(DeclaratorChunk::getFunction( - /*proto*/ true, - /*variadic*/ false, - /*ambiguous*/ false, SourceLocation(), - /*args*/ 0, 0, - /*type quals*/ 0, - /*ref-qualifier*/true, SourceLocation(), - /*const qualifier*/SourceLocation(), - /*volatile qualifier*/SourceLocation(), - /*mutable qualifier*/SourceLocation(), - /*EH*/ EST_None, SourceLocation(), 0, 0, 0, 0, - /*parens*/ loc, loc, - declarator)); + /*HasProto=*/true, + /*IsAmbiguous=*/false, + /*LParenLoc=*/NoLoc, + /*ArgInfo=*/0, + /*NumArgs=*/0, + /*EllipsisLoc=*/NoLoc, + /*RParenLoc=*/NoLoc, + /*TypeQuals=*/0, + /*RefQualifierIsLvalueRef=*/true, + /*RefQualifierLoc=*/NoLoc, + /*ConstQualifierLoc=*/NoLoc, + /*VolatileQualifierLoc=*/NoLoc, + /*MutableLoc=*/NoLoc, + EST_None, + /*ESpecLoc=*/NoLoc, + /*Exceptions=*/0, + /*ExceptionRanges=*/0, + /*NumExceptions=*/0, + /*NoexceptExpr=*/0, + loc, loc, declarator)); // For consistency, make sure the state still has us as processing // the decl spec. @@ -636,7 +646,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { // "<proto1,proto2>" is an objc qualified ID with a missing id. if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) { Result = Context.getObjCObjectType(Context.ObjCBuiltinIdTy, - (ObjCProtocolDecl**)PQ, + (ObjCProtocolDecl*const*)PQ, DS.getNumProtocolQualifiers()); Result = Context.getObjCObjectPointerType(Result); break; @@ -698,11 +708,15 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { case DeclSpec::TSW_longlong: Result = Context.LongLongTy; - // long long is a C99 feature. - if (!S.getLangOpts().C99) - S.Diag(DS.getTypeSpecWidthLoc(), - S.getLangOpts().CPlusPlus0x ? - diag::warn_cxx98_compat_longlong : diag::ext_longlong); + // 'long long' is a C99 or C++11 feature. + if (!S.getLangOpts().C99) { + if (S.getLangOpts().CPlusPlus) + S.Diag(DS.getTypeSpecWidthLoc(), + S.getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong); + else + S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_c99_longlong); + } break; } } else { @@ -713,11 +727,15 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { case DeclSpec::TSW_longlong: Result = Context.UnsignedLongLongTy; - // long long is a C99 feature. - if (!S.getLangOpts().C99) - S.Diag(DS.getTypeSpecWidthLoc(), - S.getLangOpts().CPlusPlus0x ? - diag::warn_cxx98_compat_longlong : diag::ext_longlong); + // 'long long' is a C99 or C++11 feature. + if (!S.getLangOpts().C99) { + if (S.getLangOpts().CPlusPlus) + S.Diag(DS.getTypeSpecWidthLoc(), + S.getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong); + else + S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_c99_longlong); + } break; } } @@ -753,7 +771,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { case DeclSpec::TST_class: case DeclSpec::TST_enum: case DeclSpec::TST_union: - case DeclSpec::TST_struct: { + case DeclSpec::TST_struct: + case DeclSpec::TST_interface: { TypeDecl *D = dyn_cast_or_null<TypeDecl>(DS.getRepAsDecl()); if (!D) { // This can happen in C++ with ambiguous lookups. @@ -794,18 +813,18 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { if (DS.getNumProtocolQualifiers()) Result = Context.getObjCObjectType(Result, - (ObjCProtocolDecl**) PQ, + (ObjCProtocolDecl*const*) PQ, DS.getNumProtocolQualifiers()); } else if (Result->isObjCIdType()) { // id<protocol-list> Result = Context.getObjCObjectType(Context.ObjCBuiltinIdTy, - (ObjCProtocolDecl**) PQ, + (ObjCProtocolDecl*const*) PQ, DS.getNumProtocolQualifiers()); Result = Context.getObjCObjectPointerType(Result); } else if (Result->isObjCClassType()) { // Class<protocol-list> Result = Context.getObjCObjectType(Context.ObjCBuiltinClassTy, - (ObjCProtocolDecl**) PQ, + (ObjCProtocolDecl*const*) PQ, DS.getNumProtocolQualifiers()); Result = Context.getObjCObjectPointerType(Result); } else { @@ -1853,30 +1872,31 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, case TTK_Struct: Error = 1; /* Struct member */ break; case TTK_Union: Error = 2; /* Union member */ break; case TTK_Class: Error = 3; /* Class member */ break; + case TTK_Interface: Error = 4; /* Interface member */ break; } break; case Declarator::CXXCatchContext: case Declarator::ObjCCatchContext: - Error = 4; // Exception declaration + Error = 5; // Exception declaration break; case Declarator::TemplateParamContext: - Error = 5; // Template parameter + Error = 6; // Template parameter break; case Declarator::BlockLiteralContext: - Error = 6; // Block literal + Error = 7; // Block literal break; case Declarator::TemplateTypeArgContext: - Error = 7; // Template type argument + Error = 8; // Template type argument break; case Declarator::AliasDeclContext: case Declarator::AliasTemplateContext: - Error = 9; // Type alias + Error = 10; // Type alias break; case Declarator::TrailingReturnContext: - Error = 10; // Function return type + Error = 11; // Function return type break; case Declarator::TypeNameContext: - Error = 11; // Generic + Error = 12; // Generic break; case Declarator::FileContext: case Declarator::BlockContext: @@ -1887,11 +1907,11 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, } if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) - Error = 8; + Error = 9; // In Objective-C it is an error to use 'auto' on a function declarator. if (D.isFunctionDeclarator()) - Error = 10; + Error = 11; // C++11 [dcl.spec.auto]p2: 'auto' is always fine if the declarator // contains a trailing return type. That is only legal at the outermost @@ -2149,16 +2169,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, ASTContext &Context = S.Context; const LangOptions &LangOpts = S.getLangOpts(); - bool ImplicitlyNoexcept = false; - if (D.getName().getKind() == UnqualifiedId::IK_OperatorFunctionId && - LangOpts.CPlusPlus0x) { - OverloadedOperatorKind OO = D.getName().OperatorFunctionId.Operator; - /// In C++0x, deallocation functions (normal and array operator delete) - /// are implicitly noexcept. - if (OO == OO_Delete || OO == OO_Array_Delete) - ImplicitlyNoexcept = true; - } - // The name we're declaring, if any. DeclarationName Name; if (D.getIdentifier()) @@ -2558,12 +2568,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, Exceptions, EPI); - if (FTI.getExceptionSpecType() == EST_None && - ImplicitlyNoexcept && chunkIndex == 0) { - // Only the outermost chunk is marked noexcept, of course. - EPI.ExceptionSpecType = EST_BasicNoexcept; - } - T = Context.getFunctionType(T, ArgTys.data(), ArgTys.size(), EPI); } @@ -2657,6 +2661,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // C++0x [dcl.constexpr]p8: A constexpr specifier for a non-static member // function that is not a constructor declares that function to be const. + // FIXME: This should be deferred until we know whether this is a static + // member function (for an out-of-class definition, we don't know + // this until we perform redeclaration lookup). if (D.getDeclSpec().isConstexprSpecified() && !FreeFunction && D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static && D.getName().getKind() != UnqualifiedId::IK_ConstructorName && @@ -2668,6 +2675,12 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(), FnTy->getNumArgs(), EPI); + // Rebuild any parens around the identifier in the function type. + for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { + if (D.getTypeObject(i).Kind != DeclaratorChunk::Paren) + break; + T = S.BuildParenType(T); + } } // C++11 [dcl.fct]p6 (w/DR1417): @@ -2721,6 +2734,12 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(), FnTy->getNumArgs(), EPI); + // Rebuild any parens around the identifier in the function type. + for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { + if (D.getTypeObject(i).Kind != DeclaratorChunk::Paren) + break; + T = S.BuildParenType(T); + } } } @@ -2985,6 +3004,8 @@ static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) { return AttributeList::AT_Pascal; case AttributedType::attr_pcs: return AttributeList::AT_Pcs; + case AttributedType::attr_pnaclcall: + return AttributeList::AT_PnaclCall; } llvm_unreachable("unexpected attribute kind!"); } @@ -3271,6 +3292,8 @@ namespace { TL.setLocalRangeEnd(Chunk.EndLoc); const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun; + TL.setLParenLoc(FTI.getLParenLoc()); + TL.setRParenLoc(FTI.getRParenLoc()); for (unsigned i = 0, e = TL.getNumArgs(), tpi = 0; i != e; ++i) { ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param); TL.setArg(tpi++, Param); @@ -3588,7 +3611,7 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, // Forbid __weak if the runtime doesn't support it. if (lifetime == Qualifiers::OCL_Weak && - !S.getLangOpts().ObjCRuntimeHasWeak && !NonObjCPointer) { + !S.getLangOpts().ObjCARCWeak && !NonObjCPointer) { // Actually, delay this until we know what we're parsing. if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { @@ -3611,11 +3634,12 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, while (const PointerType *ptr = T->getAs<PointerType>()) T = ptr->getPointeeType(); if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) { - ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl(); - if (Class->isArcWeakrefUnavailable()) { - S.Diag(AttrLoc, diag::err_arc_unsupported_weak_class); - S.Diag(ObjT->getInterfaceDecl()->getLocation(), - diag::note_class_declared); + if (ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl()) { + if (Class->isArcWeakrefUnavailable()) { + S.Diag(AttrLoc, diag::err_arc_unsupported_weak_class); + S.Diag(ObjT->getInterfaceDecl()->getLocation(), + diag::note_class_declared); + } } } } @@ -3875,14 +3899,14 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, return true; } + // Delay if the type didn't work out to a function. + if (!unwrapped.isFunctionType()) return false; + // Otherwise, a calling convention. CallingConv CC; if (S.CheckCallingConvAttr(attr, CC)) return true; - // Delay if the type didn't work out to a function. - if (!unwrapped.isFunctionType()) return false; - const FunctionType *fn = unwrapped.get(); CallingConv CCOld = fn->getCallConv(); if (S.Context.getCanonicalCallConv(CC) == @@ -4429,6 +4453,20 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, return RequireCompleteType(Loc, T, Diagnoser); } +/// \brief Get diagnostic %select index for tag kind for +/// literal type diagnostic message. +/// WARNING: Indexes apply to particular diagnostics only! +/// +/// \returns diagnostic %select index. +static unsigned getLiteralDiagFromTagKind(TagTypeKind Tag) { + switch (Tag) { + case TTK_Struct: return 0; + case TTK_Interface: return 1; + case TTK_Class: return 2; + default: llvm_unreachable("Invalid tag kind for literal type diagnostic!"); + } +} + /// @brief Ensure that the type T is a literal type. /// /// This routine checks whether the type @p T is a literal type. If @p T is an @@ -4485,7 +4523,7 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T, // of constexpr constructors. if (RD->getNumVBases()) { Diag(RD->getLocation(), diag::note_non_literal_virtual_base) - << RD->isStruct() << RD->getNumVBases(); + << getLiteralDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases(); for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), E = RD->vbases_end(); I != E; ++I) Diag(I->getLocStart(), @@ -4578,15 +4616,21 @@ static QualType getDecltypeForExpr(Sema &S, Expr *E) { // member access (5.2.5), decltype(e) is the type of the entity named // by e. If there is no such entity, or if e names a set of overloaded // functions, the program is ill-formed; + // + // We apply the same rules for Objective-C ivar and property references. if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())) return VD->getType(); - } - if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) { + } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) { if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) return FD->getType(); + } else if (const ObjCIvarRefExpr *IR = dyn_cast<ObjCIvarRefExpr>(E)) { + return IR->getDecl()->getType(); + } else if (const ObjCPropertyRefExpr *PR = dyn_cast<ObjCPropertyRefExpr>(E)) { + if (PR->isExplicitProperty()) + return PR->getExplicitProperty()->getType(); } - + // C++11 [expr.lambda.prim]p18: // Every occurrence of decltype((x)) where x is a possibly // parenthesized id-expression that names an entity of automatic |