From 5362a71c02e7d448a8ce98cf00c47e353fba5d04 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sat, 4 Jul 2009 13:58:54 +0000 Subject: Import Clang r74788. --- lib/Sema/JumpDiagnostics.cpp | 6 +- lib/Sema/Sema.cpp | 4 + lib/Sema/Sema.h | 92 ++++- lib/Sema/SemaAttr.cpp | 2 +- lib/Sema/SemaChecking.cpp | 55 ++- lib/Sema/SemaDecl.cpp | 93 +++-- lib/Sema/SemaDeclAttr.cpp | 111 +++--- lib/Sema/SemaDeclCXX.cpp | 168 +++++---- lib/Sema/SemaDeclObjC.cpp | 155 ++++----- lib/Sema/SemaExpr.cpp | 575 ++++++++++++++++++------------- lib/Sema/SemaExprCXX.cpp | 8 +- lib/Sema/SemaExprObjC.cpp | 34 +- lib/Sema/SemaInherit.cpp | 4 +- lib/Sema/SemaInit.cpp | 29 +- lib/Sema/SemaLookup.cpp | 42 ++- lib/Sema/SemaOverload.cpp | 72 +++- lib/Sema/SemaStmt.cpp | 6 +- lib/Sema/SemaTemplate.cpp | 55 ++- lib/Sema/SemaTemplateDeduction.cpp | 134 +++++-- lib/Sema/SemaTemplateInstantiate.cpp | 102 ++++-- lib/Sema/SemaTemplateInstantiateDecl.cpp | 124 +++++-- lib/Sema/SemaTemplateInstantiateExpr.cpp | 59 +++- lib/Sema/SemaType.cpp | 79 ++++- 23 files changed, 1288 insertions(+), 721 deletions(-) (limited to 'lib/Sema') diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp index 425d80443955..ae863f2df1ee 100644 --- a/lib/Sema/JumpDiagnostics.cpp +++ b/lib/Sema/JumpDiagnostics.cpp @@ -77,11 +77,11 @@ JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s) : S(s) { /// GetDiagForGotoScopeDecl - If this decl induces a new goto scope, return a /// diagnostic that should be emitted if control goes over it. If not, return 0. -static unsigned GetDiagForGotoScopeDecl(ASTContext &Context, const Decl *D) { +static unsigned GetDiagForGotoScopeDecl(const Decl *D) { if (const VarDecl *VD = dyn_cast(D)) { if (VD->getType()->isVariablyModifiedType()) return diag::note_protected_by_vla; - if (VD->hasAttr(Context)) + if (VD->hasAttr()) return diag::note_protected_by_cleanup; } else if (const TypedefDecl *TD = dyn_cast(D)) { if (TD->getUnderlyingType()->isVariablyModifiedType()) @@ -125,7 +125,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) { for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); I != E; ++I) { // If this decl causes a new scope, push and switch to it. - if (unsigned Diag = GetDiagForGotoScopeDecl(this->S.Context, *I)) { + if (unsigned Diag = GetDiagForGotoScopeDecl(*I)) { Scopes.push_back(GotoScope(ParentScope, Diag, (*I)->getLocation())); ParentScope = Scopes.size()-1; } diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index c37f66dae907..d1e8e2104d50 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -345,3 +345,7 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() { = SemaRef.ActiveTemplateInstantiations.back(); } } + +void Sema::ActOnComment(SourceRange Comment) { + Context.Comments.push_back(Comment); +} diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 2d27ccc77839..7af80c0261e4 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -29,9 +29,9 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" +#include #include #include -#include #include namespace llvm { @@ -86,6 +86,7 @@ namespace clang { class ObjCMethodDecl; class ObjCPropertyDecl; class ObjCContainerDecl; + class FunctionProtoType; class BasePaths; struct MemberLookupCriteria; class CXXTemporary; @@ -362,6 +363,8 @@ public: return CurBlock ? CurBlock->SwitchStack : FunctionSwitchStack; } + virtual void ActOnComment(SourceRange Comment); + //===--------------------------------------------------------------------===// // Type Analysis / Processing: SemaType.cpp. // @@ -392,6 +395,9 @@ public: DeclarationName GetNameForDeclarator(Declarator &D); bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range); bool CheckDistantExceptionSpec(QualType T); + bool CheckEquivalentExceptionSpec( + const FunctionProtoType *Old, SourceLocation OldLoc, + const FunctionProtoType *New, SourceLocation NewLoc); QualType ObjCGetTypeForMethodDefinition(DeclPtrTy D); @@ -406,6 +412,9 @@ public: QualType getQualifiedNameType(const CXXScopeSpec &SS, QualType T); + QualType BuildTypeofExprType(Expr *E); + QualType BuildDecltypeType(Expr *E); + //===--------------------------------------------------------------------===// // Symbol table / Decl tracking callbacks: SemaDecl.cpp. // @@ -482,7 +491,7 @@ public: void DiagnoseUnusedParameters(InputIterator Param, InputIterator ParamEnd) { for (; Param != ParamEnd; ++Param) { if (!(*Param)->isUsed() && (*Param)->getDeclName() && - !(*Param)->template hasAttr(Context)) + !(*Param)->template hasAttr()) Diag((*Param)->getLocation(), diag::warn_unused_parameter) << (*Param)->getDeclName(); } @@ -679,7 +688,7 @@ public: OR_Deleted ///< Overload resoltuion refers to a deleted function. }; - typedef llvm::SmallPtrSet FunctionSet; + typedef llvm::SmallPtrSet FunctionSet; typedef llvm::SmallPtrSet AssociatedNamespaceSet; typedef llvm::SmallPtrSet AssociatedClassSet; @@ -698,6 +707,9 @@ public: bool SuppressUserConversions = false, bool ForceRValue = false); void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, + bool HasExplicitTemplateArgs, + const TemplateArgument *ExplicitTemplateArgs, + unsigned NumExplicitTemplateArgs, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions = false, @@ -744,6 +756,9 @@ public: FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, DeclarationName UnqualifiedName, + bool HasExplicitTemplateArgs, + const TemplateArgument *ExplicitTemplateArgs, + unsigned NumExplicitTemplateArgs, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, SourceLocation *CommaLocs, @@ -1398,7 +1413,11 @@ public: bool HasTrailingLParen, const CXXScopeSpec *SS, bool isAddressOfOperand = false); - + OwningExprResult BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D, + bool HasTrailingLParen, + const CXXScopeSpec *SS, + bool isAddressOfOperand); + virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); virtual OwningExprResult ActOnNumericConstant(const Token &); @@ -1594,9 +1613,9 @@ public: QualType DeclInitType, Expr **Exprs, unsigned NumExprs); - /// MarcDestructorReferenced - Prepare for calling destructor on the + /// MarkDestructorReferenced - Prepare for calling destructor on the /// constructed decl. - void MarcDestructorReferenced(SourceLocation Loc, QualType DeclInitType); + void MarkDestructorReferenced(SourceLocation Loc, QualType DeclInitType); /// DefineImplicitDefaultConstructor - Checks for feasibility of /// defining this constructor as the default constructor. @@ -1884,7 +1903,9 @@ public: virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorD, Scope *S, + const CXXScopeSpec &SS, IdentifierInfo *MemberOrBase, + TypeTy *TemplateTypeTy, SourceLocation IdLoc, SourceLocation LParenLoc, ExprTy **Args, unsigned NumArgs, @@ -2068,6 +2089,20 @@ public: SourceLocation *TemplateArgLocs, SourceLocation RAngleLoc); + OwningExprResult BuildTemplateIdExpr(TemplateName Template, + SourceLocation TemplateNameLoc, + SourceLocation LAngleLoc, + const TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs, + SourceLocation RAngleLoc); + + virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template, + SourceLocation TemplateNameLoc, + SourceLocation LAngleLoc, + ASTTemplateArgsPtr TemplateArgs, + SourceLocation *TemplateArgLocs, + SourceLocation RAngleLoc); + virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc, const IdentifierInfo &Name, SourceLocation NameLoc, @@ -2134,6 +2169,7 @@ public: const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs, SourceLocation RAngleLoc, + bool PartialTemplateArgs, TemplateArgumentListBuilder &Converted); bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, @@ -2225,7 +2261,10 @@ public: TDK_TooManyArguments, /// \brief When performing template argument deduction for a class /// template, there were too few call arguments. - TDK_TooFewArguments + TDK_TooFewArguments, + /// \brief The explicitly-specified template arguments were not valid + /// template arguments for the given template. + TDK_InvalidExplicitArguments }; /// \brief Provides information about an attempted template argument @@ -2307,6 +2346,9 @@ public: TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, + bool HasExplicitTemplateArgs, + const TemplateArgument *ExplicitTemplateArgs, + unsigned NumExplicitTemplateArgs, Expr **Args, unsigned NumArgs, FunctionDecl *&Specialization, TemplateDeductionInfo &Info); @@ -2323,7 +2365,7 @@ public: /// \brief A template instantiation that is currently in progress. struct ActiveTemplateInstantiation { /// \brief The kind of template instantiation we are performing - enum { + enum InstantiationKind { /// We are instantiating a template declaration. The entity is /// the declaration we're instantiating (e.g., a CXXRecordDecl). TemplateInstantiation, @@ -2335,13 +2377,16 @@ public: /// FIXME: Use a TemplateArgumentList DefaultTemplateArgumentInstantiation, - /// We are performing template argument deduction for a class - /// template partial specialization. The Entity is the class - /// template partial specialization, and - /// TemplateArgs/NumTemplateArgs provides the deduced template - /// arguments. - /// FIXME: Use a TemplateArgumentList - PartialSpecDeductionInstantiation + /// We are substituting explicit template arguments provided for + /// a function template. The entity is a FunctionTemplateDecl. + ExplicitTemplateArgumentSubstitution, + + /// We are substituting template argument determined as part of + /// template argument deduction for either a class template + /// partial specialization or a function template. The + /// Entity is either a ClassTemplatePartialSpecializationDecl or + /// a FunctionTemplateDecl. + DeducedTemplateArgumentSubstitution } Kind; /// \brief The point of instantiation within the source code. @@ -2375,7 +2420,8 @@ public: return true; case DefaultTemplateArgumentInstantiation: - case PartialSpecDeductionInstantiation: + case ExplicitTemplateArgumentSubstitution: + case DeducedTemplateArgumentSubstitution: return X.TemplateArgs == Y.TemplateArgs; } @@ -2432,6 +2478,15 @@ public: unsigned NumTemplateArgs, SourceRange InstantiationRange = SourceRange()); + /// \brief Note that we are instantiating a default argument in a + /// template-id. + InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + FunctionTemplateDecl *FunctionTemplate, + const TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs, + ActiveTemplateInstantiation::InstantiationKind Kind, + SourceRange InstantiationRange = SourceRange()); + /// \brief Note that we are instantiating as part of template /// argument deduction for a class template partial /// specialization. @@ -2574,7 +2629,7 @@ public: /// \brief The queue of implicit template instantiations that are required /// but have not yet been performed. - std::queue PendingImplicitInstantiations; + std::deque PendingImplicitInstantiations; void PerformPendingImplicitInstantiations(); @@ -2629,7 +2684,8 @@ public: const TemplateArgumentList &TemplateArgs); void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, - FunctionDecl *Function); + FunctionDecl *Function, + bool Recursive = false); void InstantiateVariableDefinition(VarDecl *Var); NamedDecl *InstantiateCurrentDeclRef(NamedDecl *D); diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index cbfa56a6911f..1bf8444c42b7 100644 --- a/lib/Sema/SemaAttr.cpp +++ b/lib/Sema/SemaAttr.cpp @@ -205,7 +205,7 @@ void Sema::ActOnPragmaUnused(ExprTy **Exprs, unsigned NumExprs, // Otherwise, add the 'unused' attribute to each referenced declaration. for (unsigned i = 0; i < NumExprs; ++i) { DeclRefExpr *DR = (DeclRefExpr*) Exprs[i]; - DR->getDecl()->addAttr(Context, ::new (Context) UnusedAttr()); + DR->getDecl()->addAttr(::new (Context) UnusedAttr()); DR->Destroy(Context); } } diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index f6d6623f9a20..4eed01872246 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -166,7 +166,7 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { // handlers. // Printf checking. - if (const FormatAttr *Format = FDecl->getAttr(Context)) { + if (const FormatAttr *Format = FDecl->getAttr()) { if (Format->getType() == "printf") { bool HasVAListArg = Format->getFirstArg() == 0; if (!HasVAListArg) { @@ -178,7 +178,7 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { HasVAListArg ? 0 : Format->getFirstArg() - 1); } } - for (const Attr *attr = FDecl->getAttrs(Context); + for (const Attr *attr = FDecl->getAttrs(); attr; attr = attr->getNext()) { if (const NonNullAttr *NonNull = dyn_cast(attr)) CheckNonNullArguments(NonNull, TheCall); @@ -192,7 +192,7 @@ Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) { OwningExprResult TheCallResult(Owned(TheCall)); // Printf checking. - const FormatAttr *Format = NDecl->getAttr(Context); + const FormatAttr *Format = NDecl->getAttr(); if (!Format) return move(TheCallResult); const VarDecl *V = dyn_cast(NDecl); @@ -717,8 +717,6 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, if (E->isTypeDependent() || E->isValueDependent()) return false; - E = E->IgnoreParenCasts(); - switch (E->getStmtClass()) { case Stmt::ConditionalOperatorClass: { const ConditionalOperator *C = cast(E); @@ -763,6 +761,28 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, return SemaCheckStringLiteral(Init, TheCall, HasVAListArg, format_idx, firstDataArg); } + + // For vprintf* functions (i.e., HasVAListArg==true), we add a + // special check to see if the format string is a function parameter + // of the function calling the printf function. If the function + // has an attribute indicating it is a printf-like function, then we + // should suppress warnings concerning non-literals being used in a call + // to a vprintf function. For example: + // + // void + // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...){ + // va_list ap; + // va_start(ap, fmt); + // vprintf(fmt, ap); // Do NOT emit a warning about "fmt". + // ... + // + // + // FIXME: We don't have full attribute support yet, so just check to see + // if the argument is a DeclRefExpr that references a parameter. We'll + // add proper support for checking the attribute later. + if (HasVAListArg) + if (isa(VD)) + return true; } return false; @@ -774,7 +794,7 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, = dyn_cast(CE->getCallee())) { if (const DeclRefExpr *DRE = dyn_cast(ICE->getSubExpr())) { if (const FunctionDecl *FD = dyn_cast(DRE->getDecl())) { - if (const FormatArgAttr *FA = FD->getAttr(Context)) { + if (const FormatArgAttr *FA = FD->getAttr()) { unsigned ArgIndex = FA->getFormatIdx(); const Expr *Arg = CE->getArg(ArgIndex - 1); @@ -901,29 +921,6 @@ Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg, firstDataArg)) return; // Literal format string found, check done! - // For vprintf* functions (i.e., HasVAListArg==true), we add a - // special check to see if the format string is a function parameter - // of the function calling the printf function. If the function - // has an attribute indicating it is a printf-like function, then we - // should suppress warnings concerning non-literals being used in a call - // to a vprintf function. For example: - // - // void - // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...) { - // va_list ap; - // va_start(ap, fmt); - // vprintf(fmt, ap); // Do NOT emit a warning about "fmt". - // ... - // - // - // FIXME: We don't have full attribute support yet, so just check to see - // if the argument is a DeclRefExpr that references a parameter. We'll - // add proper support for checking the attribute later. - if (HasVAListArg) - if (const DeclRefExpr *DR = dyn_cast(OrigFormatExpr)) - if (isa(DR->getDecl())) - return; - // If there are no arguments specified, warn with -Wformat-security, otherwise // warn only with -Wformat-nonliteral. if (TheCall->getNumArgs() == format_idx+1) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 13162d8e8ea9..1fd569729a37 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -256,7 +256,7 @@ static bool AllowOverloadingOfFunction(Decl *PrevDecl, ASTContext &Context) { if (isa(PrevDecl)) return true; - return PrevDecl->getAttr(Context) != 0; + return PrevDecl->getAttr() != 0; } /// Add this decl to the scope shadowed decl chains. @@ -273,7 +273,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) { // Add scoped declarations into their context, so that they can be // found later. Declarations without a context won't be inserted // into any context. - CurContext->addDecl(Context, D); + CurContext->addDecl(D); // C++ [basic.scope]p4: // -- exactly one declaration shall declare a class name or @@ -612,8 +612,8 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) { /// DeclhasAttr - returns true if decl Declaration already has the target /// attribute. static bool -DeclHasAttr(ASTContext &Context, const Decl *decl, const Attr *target) { - for (const Attr *attr = decl->getAttrs(Context); attr; attr = attr->getNext()) +DeclHasAttr(const Decl *decl, const Attr *target) { + for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext()) if (attr->getKind() == target->getKind()) return true; @@ -622,11 +622,11 @@ DeclHasAttr(ASTContext &Context, const Decl *decl, const Attr *target) { /// MergeAttributes - append attributes from the Old decl to the New one. static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) { - for (const Attr *attr = Old->getAttrs(C); attr; attr = attr->getNext()) { - if (!DeclHasAttr(C, New, attr) && attr->isMerged()) { + for (const Attr *attr = Old->getAttrs(); attr; attr = attr->getNext()) { + if (!DeclHasAttr(New, attr) && attr->isMerged()) { Attr *NewAttr = attr->clone(C); NewAttr->setInherited(true); - New->addAttr(C, NewAttr); + New->addAttr(NewAttr); } } } @@ -1123,8 +1123,8 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) { bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner, RecordDecl *AnonRecord) { bool Invalid = false; - for (RecordDecl::field_iterator F = AnonRecord->field_begin(Context), - FEnd = AnonRecord->field_end(Context); + for (RecordDecl::field_iterator F = AnonRecord->field_begin(), + FEnd = AnonRecord->field_end(); F != FEnd; ++F) { if ((*F)->getDeclName()) { NamedDecl *PrevDecl = LookupQualifiedName(Owner, (*F)->getDeclName(), @@ -1147,7 +1147,7 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner, // definition, the members of the anonymous union are // considered to have been defined in the scope in which the // anonymous union is declared. - Owner->makeDeclVisibleInContext(Context, *F); + Owner->makeDeclVisibleInContext(*F); S->AddDecl(DeclPtrTy::make(*F)); IdResolver.AddDecl(*F); } @@ -1213,8 +1213,8 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // The member-specification of an anonymous union shall only // define non-static data members. [Note: nested types and // functions cannot be declared within an anonymous union. ] - for (DeclContext::decl_iterator Mem = Record->decls_begin(Context), - MemEnd = Record->decls_end(Context); + for (DeclContext::decl_iterator Mem = Record->decls_begin(), + MemEnd = Record->decls_end(); Mem != MemEnd; ++Mem) { if (FieldDecl *FD = dyn_cast(*Mem)) { // C++ [class.union]p3: @@ -1302,7 +1302,7 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // Add the anonymous struct/union object to the current // context. We'll be referencing this object when we refer to one of // its members. - Owner->addDecl(Context, Anon); + Owner->addDecl(Anon); // Inject the members of the anonymous struct/union into the owning // context and into the identifier resolver chain for name lookup @@ -1851,8 +1851,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (Expr *E = (Expr*) D.getAsmLabel()) { // The parser guarantees this is a string. StringLiteral *SE = cast(E); - NewVD->addAttr(Context, - ::new (Context) AsmLabelAttr(std::string(SE->getStrData(), + NewVD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(), SE->getByteLength()))); } @@ -1931,11 +1930,11 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl, } if (NewVD->hasLocalStorage() && T.isObjCGCWeak() - && !NewVD->hasAttr(Context)) + && !NewVD->hasAttr()) Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local); bool isVM = T->isVariablyModifiedType(); - if (isVM || NewVD->hasAttr(Context)) + if (isVM || NewVD->hasAttr()) CurFunctionNeedsScopeChecking = true; if ((isVM && NewVD->hasLinkage()) || @@ -1990,12 +1989,12 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl, return NewVD->setInvalidDecl(); } - if (!NewVD->hasLocalStorage() && NewVD->hasAttr(Context)) { + if (!NewVD->hasLocalStorage() && NewVD->hasAttr()) { Diag(NewVD->getLocation(), diag::err_block_on_nonlocal); return NewVD->setInvalidDecl(); } - if (isVM && NewVD->hasAttr(Context)) { + if (isVM && NewVD->hasAttr()) { Diag(NewVD->getLocation(), diag::err_block_on_vm); return NewVD->setInvalidDecl(); } @@ -2251,8 +2250,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (Expr *E = (Expr*) D.getAsmLabel()) { // The parser guarantees this is a string. StringLiteral *SE = cast(E); - NewFD->addAttr(Context, - ::new (Context) AsmLabelAttr(std::string(SE->getStrData(), + NewFD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(), SE->getByteLength()))); } @@ -2371,7 +2369,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, ProcessDeclAttributes(S, NewFD, D); AddKnownFunctionAttributes(NewFD); - if (OverloadableAttrRequired && !NewFD->getAttr(Context)) { + if (OverloadableAttrRequired && !NewFD->getAttr()) { // If a function name is overloadable in C, then every function // with that name must be marked "overloadable". Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing) @@ -2379,7 +2377,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (PrevDecl) Diag(PrevDecl->getLocation(), diag::note_attribute_overloadable_prev_overload); - NewFD->addAttr(Context, ::new (Context) OverloadableAttr()); + NewFD->addAttr(::new (Context) OverloadableAttr()); } // If this is a locally-scoped extern C function, update the @@ -2797,7 +2795,7 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) { InitializeVarWithConstructor(Var, Constructor, InitType, 0, 0); // FIXME. Must do all that is needed to destroy the object // on scope exit. For now, just mark the destructor as used. - MarcDestructorReferenced(Var->getLocation(), InitType); + MarkDestructorReferenced(Var->getLocation(), InitType); } } } @@ -2998,7 +2996,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { ProcessDeclAttributes(S, New, D); - if (New->hasAttr(Context)) { + if (New->hasAttr()) { Diag(New->getLocation(), diag::err_block_on_nonlocal); } return DeclPtrTy::make(New); @@ -3065,7 +3063,7 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) { // See if this is a redefinition. const FunctionDecl *Definition; - if (FD->getBody(Context, Definition)) { + if (FD->getBody(Definition)) { Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName(); Diag(Definition->getLocation(), diag::note_previous_definition); } @@ -3128,10 +3126,10 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) { // Checking attributes of current function definition // dllimport attribute. - if (FD->getAttr(Context) && - (!FD->getAttr(Context))) { + if (FD->getAttr() && + (!FD->getAttr())) { // dllimport attribute cannot be applied to definition. - if (!(FD->getAttr(Context))->isInherited()) { + if (!(FD->getAttr())->isInherited()) { Diag(FD->getLocation(), diag::err_attribute_can_be_applied_only_to_symbol_declaration) << "dllimport"; @@ -3313,9 +3311,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { unsigned FormatIdx; bool HasVAListArg; if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) { - if (!FD->getAttr(Context)) - FD->addAttr(Context, - ::new (Context) FormatAttr("printf", FormatIdx + 1, + if (!FD->getAttr()) + FD->addAttr(::new (Context) FormatAttr("printf", FormatIdx + 1, HasVAListArg ? 0 : FormatIdx + 2)); } @@ -3324,8 +3321,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { // IRgen to use LLVM intrinsics for such functions. if (!getLangOptions().MathErrno && Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) { - if (!FD->getAttr(Context)) - FD->addAttr(Context, ::new (Context) ConstAttr()); + if (!FD->getAttr()) + FD->addAttr(::new (Context) ConstAttr()); } } @@ -3343,17 +3340,15 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { return; if (Name->isStr("NSLog") || Name->isStr("NSLogv")) { - if (const FormatAttr *Format = FD->getAttr(Context)) { + if (const FormatAttr *Format = FD->getAttr()) { // FIXME: We known better than our headers. const_cast(Format)->setType("printf"); } else - FD->addAttr(Context, - ::new (Context) FormatAttr("printf", 1, + FD->addAttr(::new (Context) FormatAttr("printf", 1, Name->isStr("NSLogv") ? 0 : 2)); } else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) { - if (!FD->getAttr(Context)) - FD->addAttr(Context, - ::new (Context) FormatAttr("printf", 2, + if (!FD->getAttr()) + FD->addAttr(::new (Context) FormatAttr("printf", 2, Name->isStr("vasprintf") ? 0 : 3)); } } @@ -3709,7 +3704,7 @@ CreateNewDecl: // the #pragma tokens are effectively skipped over during the // parsing of the struct). if (unsigned Alignment = getPragmaPackAlignment()) - New->addAttr(Context, ::new (Context) PackedAttr(Alignment * 8)); + New->addAttr(::new (Context) PackedAttr(Alignment * 8)); } if (getLangOptions().CPlusPlus && SS.isEmpty() && Name && !Invalid) { @@ -3761,7 +3756,7 @@ CreateNewDecl: S = getNonFieldDeclScope(S); PushOnScopeChains(New, S); } else { - CurContext->addDecl(Context, New); + CurContext->addDecl(New); } OwnedDecl = true; @@ -3917,7 +3912,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, } else if (II) { PushOnScopeChains(NewFD, S); } else - Record->addDecl(Context, NewFD); + Record->addDecl(NewFD); return NewFD; } @@ -4239,7 +4234,7 @@ void Sema::ActOnFields(Scope* S, // Add ivar's to class's DeclContext. for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { ClsFields[i]->setLexicalDeclContext(ID); - ID->addDecl(Context, ClsFields[i]); + ID->addDecl(ClsFields[i]); } // Must enforce the rule that ivars in the base classes may not be // duplicates. @@ -4250,7 +4245,7 @@ void Sema::ActOnFields(Scope* S, if (IdentifierInfo *II = Ivar->getIdentifier()) { ObjCIvarDecl* prevIvar = - ID->getSuperClass()->lookupInstanceVariable(Context, II); + ID->getSuperClass()->lookupInstanceVariable(II); if (prevIvar) { Diag(Ivar->getLocation(), diag::err_duplicate_member) << II; Diag(prevIvar->getLocation(), diag::note_previous_declaration); @@ -4549,7 +4544,7 @@ Sema::DeclPtrTy Sema::ActOnFileScopeAsmDecl(SourceLocation Loc, FileScopeAsmDecl *New = FileScopeAsmDecl::Create(Context, CurContext, Loc, AsmString); - CurContext->addDecl(Context, New); + CurContext->addDecl(New); return DeclPtrTy::make(New); } @@ -4560,7 +4555,7 @@ void Sema::ActOnPragmaWeakID(IdentifierInfo* Name, // FIXME: This implementation is an ugly hack! if (PrevDecl) { - PrevDecl->addAttr(Context, ::new (Context) WeakAttr()); + PrevDecl->addAttr(::new (Context) WeakAttr()); return; } Diag(PragmaLoc, diag::err_unsupported_pragma_weak); @@ -4576,8 +4571,8 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name, // FIXME: This implementation is an ugly hack! if (PrevDecl) { - PrevDecl->addAttr(Context, ::new (Context) AliasAttr(AliasName->getName())); - PrevDecl->addAttr(Context, ::new (Context) WeakAttr()); + PrevDecl->addAttr(::new (Context) AliasAttr(AliasName->getName())); + PrevDecl->addAttr(::new (Context) WeakAttr()); return; } Diag(PragmaLoc, diag::err_unsupported_pragma_weak); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index f7dd9303cb47..2b71df722459 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -284,7 +284,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { } if (TagDecl *TD = dyn_cast(d)) - TD->addAttr(S.Context, ::new (S.Context) PackedAttr(1)); + TD->addAttr(::new (S.Context) PackedAttr(1)); else if (FieldDecl *FD = dyn_cast(d)) { // If the alignment is less than or equal to 8 bits, the packed attribute // has no effect. @@ -293,7 +293,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) << Attr.getName() << FD->getType(); else - FD->addAttr(S.Context, ::new (S.Context) PackedAttr(1)); + FD->addAttr(::new (S.Context) PackedAttr(1)); } else S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); } @@ -308,7 +308,7 @@ static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { // The IBOutlet attribute only applies to instance variables of Objective-C // classes. if (isa(d) || isa(d)) - d->addAttr(S.Context, ::new (S.Context) IBOutletAttr()); + d->addAttr(::new (S.Context) IBOutletAttr()); else S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet); } @@ -380,7 +380,7 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { unsigned* start = &NonNullArgs[0]; unsigned size = NonNullArgs.size(); std::sort(start, start + size); - d->addAttr(S.Context, ::new (S.Context) NonNullAttr(start, size)); + d->addAttr(::new (S.Context) NonNullAttr(start, size)); } static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -405,7 +405,7 @@ static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { // FIXME: check if target symbol exists in current file - d->addAttr(S.Context, ::new (S.Context) AliasAttr(std::string(Alias, AliasLen))); + d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen))); } static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, @@ -422,7 +422,7 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, return; } - d->addAttr(S.Context, ::new (S.Context) AlwaysInlineAttr()); + d->addAttr(::new (S.Context) AlwaysInlineAttr()); } static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, @@ -447,13 +447,13 @@ static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { if (HandleCommonNoReturnAttr(d, Attr, S)) - d->addAttr(S.Context, ::new (S.Context) NoReturnAttr()); + d->addAttr(::new (S.Context) NoReturnAttr()); } static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { if (HandleCommonNoReturnAttr(d, Attr, S)) - d->addAttr(S.Context, ::new (S.Context) AnalyzerNoReturnAttr()); + d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); } static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -469,7 +469,7 @@ static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) UnusedAttr()); + d->addAttr(::new (S.Context) UnusedAttr()); } static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -490,7 +490,7 @@ static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) UsedAttr()); + d->addAttr(::new (S.Context) UsedAttr()); } static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -519,7 +519,7 @@ static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) ConstructorAttr(priority)); + d->addAttr(::new (S.Context) ConstructorAttr(priority)); } static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -548,7 +548,7 @@ static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) DestructorAttr(priority)); + d->addAttr(::new (S.Context) DestructorAttr(priority)); } static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -558,7 +558,7 @@ static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) DeprecatedAttr()); + d->addAttr(::new (S.Context) DeprecatedAttr()); } static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -568,7 +568,7 @@ static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) UnavailableAttr()); + d->addAttr(::new (S.Context) UnavailableAttr()); } static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -605,7 +605,7 @@ static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) VisibilityAttr(type)); + d->addAttr(::new (S.Context) VisibilityAttr(type)); } static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, @@ -621,7 +621,7 @@ static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, return; } - D->addAttr(S.Context, ::new (S.Context) ObjCExceptionAttr()); + D->addAttr(::new (S.Context) ObjCExceptionAttr()); } static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { @@ -637,7 +637,7 @@ static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { return; } } - D->addAttr(S.Context, ::new (S.Context) ObjCNSObjectAttr()); + D->addAttr(::new (S.Context) ObjCNSObjectAttr()); } static void @@ -652,7 +652,7 @@ HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { return; } - D->addAttr(S.Context, ::new (S.Context) OverloadableAttr()); + D->addAttr(::new (S.Context) OverloadableAttr()); } static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -676,7 +676,7 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) BlocksAttr(type)); + d->addAttr(::new (S.Context) BlocksAttr(type)); } static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -768,7 +768,7 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { << Attr.getName() << 6 /*function, method or block */; return; } - d->addAttr(S.Context, ::new (S.Context) SentinelAttr(sentinel, nullPos)); + d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); } static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { @@ -786,7 +786,7 @@ static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) return; } - Fn->addAttr(S.Context, ::new (S.Context) WarnUnusedResultAttr()); + Fn->addAttr(::new (S.Context) WarnUnusedResultAttr()); } static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { @@ -803,7 +803,7 @@ static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { return; } - D->addAttr(S.Context, ::new (S.Context) WeakAttr()); + D->addAttr(::new (S.Context) WeakAttr()); } static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { @@ -818,7 +818,7 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { if (VarDecl *VD = dyn_cast(D)) { isDef = (!VD->hasExternalStorage() || VD->getInit()); } else if (FunctionDecl *FD = dyn_cast(D)) { - isDef = FD->getBody(S.Context); + isDef = FD->getBody(); } else if (isa(D) || isa(D)) { // We ignore weak import on properties and methods return; @@ -836,7 +836,7 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { return; } - D->addAttr(S.Context, ::new (S.Context) WeakImportAttr()); + D->addAttr(::new (S.Context) WeakImportAttr()); } static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { @@ -848,7 +848,7 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { // Attribute can be applied only to functions or variables. if (isa(D)) { - D->addAttr(S.Context, ::new (S.Context) DLLImportAttr()); + D->addAttr(::new (S.Context) DLLImportAttr()); return; } @@ -876,12 +876,12 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { } } - if (D->getAttr(S.Context)) { + if (D->getAttr()) { S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; return; } - D->addAttr(S.Context, ::new (S.Context) DLLImportAttr()); + D->addAttr(::new (S.Context) DLLImportAttr()); } static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { @@ -893,7 +893,7 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { // Attribute can be applied only to functions or variables. if (isa(D)) { - D->addAttr(S.Context, ::new (S.Context) DLLExportAttr()); + D->addAttr(::new (S.Context) DLLExportAttr()); return; } @@ -912,7 +912,7 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { return; } - D->addAttr(S.Context, ::new (S.Context) DLLExportAttr()); + D->addAttr(::new (S.Context) DLLExportAttr()); } static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, @@ -934,8 +934,7 @@ static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, } WGSize[i] = (unsigned) ArgNum.getZExtValue(); } - D->addAttr(S.Context, - ::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], + D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], WGSize[2])); } @@ -955,8 +954,7 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); return; } - D->addAttr(S.Context, - ::new (S.Context) SectionAttr(std::string(SE->getStrData(), + D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(), SE->getByteLength()))); } @@ -975,13 +973,13 @@ static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { } // stdcall and fastcall attributes are mutually incompatible. - if (d->getAttr(S.Context)) { + if (d->getAttr()) { S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) << "stdcall" << "fastcall"; return; } - d->addAttr(S.Context, ::new (S.Context) StdCallAttr()); + d->addAttr(::new (S.Context) StdCallAttr()); } static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -998,13 +996,13 @@ static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { } // stdcall and fastcall attributes are mutually incompatible. - if (d->getAttr(S.Context)) { + if (d->getAttr()) { S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) << "fastcall" << "stdcall"; return; } - d->addAttr(S.Context, ::new (S.Context) FastCallAttr()); + d->addAttr(::new (S.Context) FastCallAttr()); } static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1014,7 +1012,7 @@ static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) NoThrowAttr()); + d->addAttr(::new (S.Context) NoThrowAttr()); } static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1024,7 +1022,7 @@ static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) ConstAttr()); + d->addAttr(::new (S.Context) ConstAttr()); } static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1034,7 +1032,7 @@ static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) PureAttr()); + d->addAttr(::new (S.Context) PureAttr()); } static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1092,7 +1090,7 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) CleanupAttr(FD)); + d->addAttr(::new (S.Context) CleanupAttr(FD)); } /// Handle __attribute__((format_arg((idx)))) attribute @@ -1155,7 +1153,7 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) FormatArgAttr(Idx.getZExtValue())); + d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); } /// Handle __attribute__((format(type,idx,firstarg))) attributes @@ -1296,8 +1294,7 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, - ::new (S.Context) FormatAttr(std::string(Format, FormatLen), + d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen), Idx.getZExtValue(), FirstArg.getZExtValue())); } @@ -1329,8 +1326,8 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, return; } - RecordDecl::field_iterator Field = RD->field_begin(S.Context), - FieldEnd = RD->field_end(S.Context); + RecordDecl::field_iterator Field = RD->field_begin(), + FieldEnd = RD->field_end(); if (Field == FieldEnd) { S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); return; @@ -1365,7 +1362,7 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, } } - RD->addAttr(S.Context, ::new (S.Context) TransparentUnionAttr()); + RD->addAttr(::new (S.Context) TransparentUnionAttr()); } static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1383,8 +1380,7 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); return; } - d->addAttr(S.Context, - ::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), + d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), SE->getByteLength()))); } @@ -1400,7 +1396,7 @@ static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { // FIXME: This should be the target specific maximum alignment. // (For now we just use 128 bits which is the maximum on X86). Align = 128; - d->addAttr(S.Context, ::new (S.Context) AlignedAttr(Align)); + d->addAttr(::new (S.Context) AlignedAttr(Align)); return; } @@ -1417,7 +1413,7 @@ static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); + d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); } /// HandleModeAttr - This attribute modifies the width of a decl with @@ -1598,7 +1594,7 @@ static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) NodebugAttr()); + d->addAttr(::new (S.Context) NodebugAttr()); } static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1614,7 +1610,7 @@ static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) NoinlineAttr()); + d->addAttr(::new (S.Context) NoinlineAttr()); } static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1636,7 +1632,7 @@ static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, ::new (S.Context) GNUInlineAttr()); + d->addAttr(::new (S.Context) GNUInlineAttr()); } static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1672,8 +1668,7 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(S.Context, - ::new (S.Context) RegparmAttr(NumParams.getZExtValue())); + d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); } //===----------------------------------------------------------------------===// @@ -1706,10 +1701,10 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, assert(0 && "invalid ownership attribute"); return; case AttributeList::AT_cf_returns_retained: - d->addAttr(S.Context, ::new (S.Context) CFReturnsRetainedAttr()); + d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); return; case AttributeList::AT_ns_returns_retained: - d->addAttr(S.Context, ::new (S.Context) NSReturnsRetainedAttr()); + d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); return; }; } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index cf0dab5cf298..75ceb1916555 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -258,6 +258,12 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) { } } + if (CheckEquivalentExceptionSpec( + Old->getType()->getAsFunctionProtoType(), Old->getLocation(), + New->getType()->getAsFunctionProtoType(), New->getLocation())) { + Invalid = true; + } + return Invalid; } @@ -481,7 +487,7 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, } // Attach the remaining base class specifiers to the derived class. - Class->setBases(Bases, NumGoodBases); + Class->setBases(Context, Bases, NumGoodBases); // Delete the remaining (good) base class specifiers, since their // data has been copied into the CXXRecordDecl. @@ -646,7 +652,9 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, Sema::MemInitResult Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, Scope *S, + const CXXScopeSpec &SS, IdentifierInfo *MemberOrBase, + TypeTy *TemplateTypeTy, SourceLocation IdLoc, SourceLocation LParenLoc, ExprTy **Args, unsigned NumArgs, @@ -677,28 +685,31 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, // composed of a single identifier refers to the class member. A // mem-initializer-id for the hidden base class may be specified // using a qualified name. ] - // Look for a member, first. - FieldDecl *Member = 0; - DeclContext::lookup_result Result - = ClassDecl->lookup(Context, MemberOrBase); - if (Result.first != Result.second) - Member = dyn_cast(*Result.first); - - // FIXME: Handle members of an anonymous union. - - if (Member) { - // FIXME: Perform direct initialization of the member. - return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs); + if (!SS.getScopeRep() && !TemplateTypeTy) { + // Look for a member, first. + FieldDecl *Member = 0; + DeclContext::lookup_result Result + = ClassDecl->lookup(MemberOrBase); + if (Result.first != Result.second) + Member = dyn_cast(*Result.first); + + // FIXME: Handle members of an anonymous union. + + if (Member) { + // FIXME: Perform direct initialization of the member. + return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs, + IdLoc); + } } - // It didn't name a member, so see if it names a class. - TypeTy *BaseTy = getTypeName(*MemberOrBase, IdLoc, S, 0/*SS*/); + TypeTy *BaseTy = TemplateTypeTy ? TemplateTypeTy + : getTypeName(*MemberOrBase, IdLoc, S, &SS); if (!BaseTy) return Diag(IdLoc, diag::err_mem_init_not_member_or_class) << MemberOrBase << SourceRange(IdLoc, RParenLoc); QualType BaseType = QualType::getFromOpaquePtr(BaseTy); - if (!BaseType->isRecordType()) + if (!BaseType->isRecordType() && !BaseType->isDependentType()) return Diag(IdLoc, diag::err_base_init_does_not_name_class) << BaseType << SourceRange(IdLoc, RParenLoc); @@ -749,8 +760,18 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, if (DirectBaseSpec && VirtualBaseSpec) return Diag(IdLoc, diag::err_base_init_direct_and_virtual) << MemberOrBase << SourceRange(IdLoc, RParenLoc); + // C++ [base.class.init]p2: + // Unless the mem-initializer-id names a nonstatic data membeer of the + // constructor's class ot a direst or virtual base of that class, the + // mem-initializer is ill-formed. + if (!DirectBaseSpec && !VirtualBaseSpec) + return Diag(IdLoc, diag::err_not_direct_base_or_virtual) + << BaseType << ClassDecl->getNameAsCString() + << SourceRange(IdLoc, RParenLoc); + - return new CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs); + return new CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs, + IdLoc); } void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, @@ -766,6 +787,42 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, Diag(ColonLoc, diag::err_only_constructors_take_base_inits); return; } + llvm::DenseMapMembers; + bool err = false; + for (unsigned i = 0; i < NumMemInits; i++) { + CXXBaseOrMemberInitializer *Member = + static_cast(MemInits[i]); + void *KeyToMember = Member->getBaseOrMember(); + // For fields injected into the class via declaration of an anonymous union, + // use its anonymous union class declaration as the unique key. + if (FieldDecl *Field = Member->getMember()) + if (Field->getDeclContext()->isRecord() && + cast(Field->getDeclContext())->isAnonymousStructOrUnion()) + KeyToMember = static_cast(Field->getDeclContext()); + CXXBaseOrMemberInitializer *&PrevMember = Members[KeyToMember]; + if (!PrevMember) { + PrevMember = Member; + continue; + } + if (FieldDecl *Field = Member->getMember()) + Diag(Member->getSourceLocation(), + diag::error_multiple_mem_initialization) + << Field->getNameAsString(); + else { + Type *BaseClass = Member->getBaseClass(); + assert(BaseClass && "ActOnMemInitializers - neither field or base"); + Diag(Member->getSourceLocation(), + diag::error_multiple_base_initialization) + << BaseClass->getDesugaredType(true); + } + Diag(PrevMember->getSourceLocation(), diag::note_previous_initializer) + << 0; + err = true; + } + if (!err) + Constructor->setBaseOrMemberInitializers(Context, + reinterpret_cast(MemInits), + NumMemInits); } namespace { @@ -821,8 +878,7 @@ namespace { MethodSetTy OverriddenMethods; size_t MethodsSize = Methods.size(); - for (RecordDecl::decl_iterator i = RD->decls_begin(Context), - e = RD->decls_end(Context); + for (RecordDecl::decl_iterator i = RD->decls_begin(), e = RD->decls_end(); i != e; ++i) { // Traverse the record, looking for methods. if (CXXMethodDecl *MD = dyn_cast(*i)) { @@ -919,8 +975,8 @@ namespace { bool VisitDeclContext(const DeclContext *DC) { bool Invalid = false; - for (CXXRecordDecl::decl_iterator I = DC->decls_begin(SemaRef.Context), - E = DC->decls_end(SemaRef.Context); I != E; ++I) + for (CXXRecordDecl::decl_iterator I = DC->decls_begin(), + E = DC->decls_end(); I != E; ++I) Invalid |= Visit(*I); return Invalid; @@ -996,8 +1052,8 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, AbstractClassUsageDiagnoser(*this, RD); if (RD->hasTrivialConstructor() || RD->hasTrivialDestructor()) { - for (RecordDecl::field_iterator i = RD->field_begin(Context), - e = RD->field_end(Context); i != e; ++i) { + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e; ++i) { // All the nonstatic data members must have trivial constructors. QualType FTy = i->getType(); while (const ArrayType *AT = Context.getAsArrayType(FTy)) @@ -1054,7 +1110,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { /*isImplicitlyDeclared=*/true); DefaultCon->setAccess(AS_public); DefaultCon->setImplicit(); - ClassDecl->addDecl(Context, DefaultCon); + ClassDecl->addDecl(DefaultCon); } if (!ClassDecl->hasUserDeclaredCopyConstructor()) { @@ -1086,8 +1142,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { // class type M (or array thereof), each such class type // has a copy constructor whose first parameter is of type // const M& or const volatile M&. - for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context); - HasConstCopyConstructor && Field != ClassDecl->field_end(Context); + for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(); + HasConstCopyConstructor && Field != ClassDecl->field_end(); ++Field) { QualType FieldType = (*Field)->getType(); if (const ArrayType *Array = Context.getAsArrayType(FieldType)) @@ -1131,7 +1187,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { /*IdentifierInfo=*/0, ArgType, VarDecl::None, 0); CopyConstructor->setParams(Context, &FromParam, 1); - ClassDecl->addDecl(Context, CopyConstructor); + ClassDecl->addDecl(CopyConstructor); } if (!ClassDecl->hasUserDeclaredCopyAssignment()) { @@ -1165,8 +1221,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { // type M (or array thereof), each such class type has a copy // assignment operator whose parameter is of type const M&, // const volatile M& or M. - for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context); - HasConstCopyAssignment && Field != ClassDecl->field_end(Context); + for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(); + HasConstCopyAssignment && Field != ClassDecl->field_end(); ++Field) { QualType FieldType = (*Field)->getType(); if (const ArrayType *Array = Context.getAsArrayType(FieldType)) @@ -1210,7 +1266,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { // Don't call addedAssignmentOperator. There is no way to distinguish an // implicit from an explicit assignment operator. - ClassDecl->addDecl(Context, CopyAssignment); + ClassDecl->addDecl(CopyAssignment); } if (!ClassDecl->hasUserDeclaredDestructor()) { @@ -1229,7 +1285,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { /*isImplicitlyDeclared=*/true); Destructor->setAccess(AS_public); Destructor->setImplicit(); - ClassDecl->addDecl(Context, Destructor); + ClassDecl->addDecl(Destructor); } } @@ -1772,7 +1828,7 @@ void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) { // or translation unit scope. We add UsingDirectiveDecls, into // it's lookup structure. if (DeclContext *Ctx = static_cast(S->getEntity())) - Ctx->addDecl(Context, UDir); + Ctx->addDecl(UDir); else // Otherwise it is block-sope. using-directives will affect lookup // only to the end of scope. @@ -1873,7 +1929,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S, (NestedNameSpecifier *)SS.getScopeRep(), IdentLoc, R); - CurContext->addDecl(Context, AliasDecl); + CurContext->addDecl(AliasDecl); return DeclPtrTy::make(AliasDecl); } @@ -1891,8 +1947,8 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, // for its base class and its non-static data members shall have been // implicitly defined. bool err = false; - for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(); - Base != ClassDecl->bases_end(); ++Base) { + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), + E = ClassDecl->bases_end(); Base != E; ++Base) { CXXRecordDecl *BaseClassDecl = cast(Base->getType()->getAsRecordType()->getDecl()); if (!BaseClassDecl->hasTrivialConstructor()) { @@ -1909,9 +1965,8 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, } } } - for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context); - Field != ClassDecl->field_end(Context); - ++Field) { + for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), + E = ClassDecl->field_end(); Field != E; ++Field) { QualType FieldType = Context.getCanonicalType((*Field)->getType()); if (const ArrayType *Array = Context.getAsArrayType(FieldType)) FieldType = Array->getElementType(); @@ -1964,8 +2019,8 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, // implicitly defined, all the implicitly-declared default destructors // for its base class and its non-static data members shall have been // implicitly defined. - for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(); - Base != ClassDecl->bases_end(); ++Base) { + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), + E = ClassDecl->bases_end(); Base != E; ++Base) { CXXRecordDecl *BaseClassDecl = cast(Base->getType()->getAsRecordType()->getDecl()); if (!BaseClassDecl->hasTrivialDestructor()) { @@ -1978,9 +2033,8 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, } } - for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context); - Field != ClassDecl->field_end(Context); - ++Field) { + for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), + E = ClassDecl->field_end(); Field != E; ++Field) { QualType FieldType = Context.getCanonicalType((*Field)->getType()); if (const ArrayType *Array = Context.getAsArrayType(FieldType)) FieldType = Array->getElementType(); @@ -2010,7 +2064,6 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation, CXXRecordDecl *ClassDecl = cast(MethodDecl->getDeclContext()); - assert(ClassDecl && "DefineImplicitOverloadedAssign - invalid constructor"); // C++[class.copy] p12 // Before the implicitly-declared copy assignment operator for a class is @@ -2018,17 +2071,16 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation, // for its direct base classes and its nonstatic data members shall have // been implicitly defined. bool err = false; - for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(); - Base != ClassDecl->bases_end(); ++Base) { + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), + E = ClassDecl->bases_end(); Base != E; ++Base) { CXXRecordDecl *BaseClassDecl = cast(Base->getType()->getAsRecordType()->getDecl()); if (CXXMethodDecl *BaseAssignOpMethod = getAssignOperatorMethod(MethodDecl->getParamDecl(0), BaseClassDecl)) MarkDeclarationReferenced(CurrentLocation, BaseAssignOpMethod); } - for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context); - Field != ClassDecl->field_end(Context); - ++Field) { + for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), + E = ClassDecl->field_end(); Field != E; ++Field) { QualType FieldType = Context.getCanonicalType((*Field)->getType()); if (const ArrayType *Array = Context.getAsArrayType(FieldType)) FieldType = Array->getElementType(); @@ -2113,9 +2165,9 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, BaseClassDecl->getCopyConstructor(Context, TypeQuals)) MarkDeclarationReferenced(CurrentLocation, BaseCopyCtor); } - for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context); - Field != ClassDecl->field_end(Context); - ++Field) { + for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), + FieldEnd = ClassDecl->field_end(); + Field != FieldEnd; ++Field) { QualType FieldType = Context.getCanonicalType((*Field)->getType()); if (const ArrayType *Array = Context.getAsArrayType(FieldType)) FieldType = Array->getElementType(); @@ -2140,7 +2192,7 @@ void Sema::InitializeVarWithConstructor(VarDecl *VD, VD->setInit(Context, Temp); } -void Sema::MarcDestructorReferenced(SourceLocation Loc, QualType DeclInitType) +void Sema::MarkDestructorReferenced(SourceLocation Loc, QualType DeclInitType) { CXXRecordDecl *ClassDecl = cast( DeclInitType->getAsRecordType()->getDecl()); @@ -2218,7 +2270,7 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl, (Expr**)Exprs.release(), NumExprs); // FIXME. Must do all that is needed to destroy the object // on scope exit. For now, just mark the destructor as used. - MarcDestructorReferenced(VDecl->getLocation(), DeclInitType); + MarkDestructorReferenced(VDecl->getLocation(), DeclInitType); } return; } @@ -2282,7 +2334,7 @@ Sema::PerformInitializationByConstructor(QualType ClassType, = Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(ClassType.getUnqualifiedType())); DeclContext::lookup_const_iterator Con, ConEnd; - for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(Context, ConstructorName); + for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(ConstructorName); Con != ConEnd; ++Con) { CXXConstructorDecl *Constructor = cast(*Con); if ((Kind == IK_Direct) || @@ -2892,7 +2944,7 @@ Sema::DeclPtrTy Sema::ActOnStartLinkageSpecification(Scope *S, LinkageSpecDecl *D = LinkageSpecDecl::Create(Context, CurContext, LangLoc, Language, LBraceLoc.isValid()); - CurContext->addDecl(Context, D); + CurContext->addDecl(D); PushDeclContext(S, D); return DeclPtrTy::make(D); } @@ -3006,7 +3058,7 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) { if (II) PushOnScopeChains(ExDecl, S); else - CurContext->addDecl(Context, ExDecl); + CurContext->addDecl(ExDecl); ProcessDeclAttributes(S, ExDecl, D); return DeclPtrTy::make(ExDecl); @@ -3040,7 +3092,7 @@ Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc, Decl *Decl = StaticAssertDecl::Create(Context, CurContext, AssertLoc, AssertExpr, AssertMessage); - CurContext->addDecl(Context, Decl); + CurContext->addDecl(Decl); return DeclPtrTy::make(Decl); } diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 9013726e1aee..5cf48d6da0c8 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -379,12 +379,12 @@ void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) { if (!SDecl) return; // FIXME: O(N^2) - for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(Context), - E = SDecl->prop_end(Context); S != E; ++S) { + for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(), + E = SDecl->prop_end(); S != E; ++S) { ObjCPropertyDecl *SuperPDecl = (*S); // Does property in super class has declaration in current class? - for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(Context), - E = IDecl->prop_end(Context); I != E; ++I) { + for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(), + E = IDecl->prop_end(); I != E; ++I) { ObjCPropertyDecl *PDecl = (*I); if (SuperPDecl->getIdentifier() == PDecl->getIdentifier()) DiagnosePropertyMismatch(PDecl, SuperPDecl, @@ -404,13 +404,12 @@ Sema::MergeOneProtocolPropertiesIntoClass(Decl *CDecl, // Category ObjCCategoryDecl *CatDecl = static_cast(CDecl); assert (CatDecl && "MergeOneProtocolPropertiesIntoClass"); - for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(Context), - E = PDecl->prop_end(Context); P != E; ++P) { + for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), + E = PDecl->prop_end(); P != E; ++P) { ObjCPropertyDecl *Pr = (*P); ObjCCategoryDecl::prop_iterator CP, CE; // Is this property already in category's list of properties? - for (CP = CatDecl->prop_begin(Context), CE = CatDecl->prop_end(Context); - CP != CE; ++CP) + for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP != CE; ++CP) if ((*CP)->getIdentifier() == Pr->getIdentifier()) break; if (CP != CE) @@ -419,13 +418,12 @@ Sema::MergeOneProtocolPropertiesIntoClass(Decl *CDecl, } return; } - for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(Context), - E = PDecl->prop_end(Context); P != E; ++P) { + for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), + E = PDecl->prop_end(); P != E; ++P) { ObjCPropertyDecl *Pr = (*P); ObjCInterfaceDecl::prop_iterator CP, CE; // Is this property already in class's list of properties? - for (CP = IDecl->prop_begin(Context), CE = IDecl->prop_end(Context); - CP != CE; ++CP) + for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP) if ((*CP)->getIdentifier() == Pr->getIdentifier()) break; if (CP != CE) @@ -495,16 +493,16 @@ void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, return; // Possibly due to previous error llvm::DenseMap MethodMap; - for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(Context), - e = ID->meth_end(Context); i != e; ++i) { + for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(), + e = ID->meth_end(); i != e; ++i) { ObjCMethodDecl *MD = *i; MethodMap[MD->getSelector()] = MD; } if (MethodMap.empty()) return; - for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(Context), - e = CAT->meth_end(Context); i != e; ++i) { + for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(), + e = CAT->meth_end(); i != e; ++i) { ObjCMethodDecl *Method = *i; const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()]; if (PrevMethod && !MatchTwoMethodDeclarations(Method, PrevMethod)) { @@ -539,7 +537,7 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, ObjCForwardProtocolDecl *PDecl = ObjCForwardProtocolDecl::Create(Context, CurContext, AtProtocolLoc, &Protocols[0], Protocols.size()); - CurContext->addDecl(Context, PDecl); + CurContext->addDecl(PDecl); CheckObjCDeclScope(PDecl); return DeclPtrTy::make(PDecl); } @@ -555,7 +553,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, ObjCCategoryDecl *CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, CategoryName); // FIXME: PushOnScopeChains? - CurContext->addDecl(Context, CDecl); + CurContext->addDecl(CDecl); ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName); /// Check that class of this category is already completely declared. @@ -609,7 +607,7 @@ Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation( Diag(ClassLoc, diag::err_undef_interface) << ClassName; // FIXME: PushOnScopeChains? - CurContext->addDecl(Context, CDecl); + CurContext->addDecl(CDecl); /// TODO: Check that CatName, category name, is not used in another // implementation. @@ -808,7 +806,7 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl, return false; // Even if property is ready only, if interface has a user defined setter, // it is not considered read only. - if (IDecl->getInstanceMethod(Context, PDecl->getSetterName())) + if (IDecl->getInstanceMethod(PDecl->getSetterName())) return false; // Main class has the property as 'readonly'. Must search @@ -818,10 +816,10 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl, Category; Category = Category->getNextClassCategory()) { // Even if property is ready only, if a category has a user defined setter, // it is not considered read only. - if (Category->getInstanceMethod(Context, PDecl->getSetterName())) + if (Category->getInstanceMethod(PDecl->getSetterName())) return false; ObjCPropertyDecl *P = - Category->FindPropertyDeclaration(Context, PDecl->getIdentifier()); + Category->FindPropertyDeclaration(PDecl->getIdentifier()); if (P && !P->isReadOnly()) return false; } @@ -831,19 +829,19 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl, if (ObjCMethodDecl *OMD = dyn_cast(CurContext)) { if (ObjCImplementationDecl *IMD = dyn_cast(OMD->getDeclContext())) { - if (IMD->getInstanceMethod(Context, PDecl->getSetterName())) + if (IMD->getInstanceMethod(PDecl->getSetterName())) return false; } else if (ObjCCategoryImplDecl *CIMD = dyn_cast(OMD->getDeclContext())) { - if (CIMD->getInstanceMethod(Context, PDecl->getSetterName())) + if (CIMD->getInstanceMethod(PDecl->getSetterName())) return false; } } // Lastly, look through the implementation (if one is in scope). if (ObjCImplementationDecl *ImpDecl = LookupObjCImplementation(IDecl->getIdentifier())) - if (ImpDecl->getInstanceMethod(Context, PDecl->getSetterName())) + if (ImpDecl->getInstanceMethod(PDecl->getSetterName())) return false; // If all fails, look at the super class. if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass()) @@ -890,31 +888,30 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, // check unimplemented instance methods. if (!NSIDecl) - for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(Context), - E = PDecl->instmeth_end(Context); I != E; ++I) { + for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(), + E = PDecl->instmeth_end(); I != E; ++I) { ObjCMethodDecl *method = *I; if (method->getImplementationControl() != ObjCMethodDecl::Optional && !method->isSynthesized() && !InsMap.count(method->getSelector()) && (!Super || - !Super->lookupInstanceMethod(Context, method->getSelector()))) { + !Super->lookupInstanceMethod(method->getSelector()))) { // Ugly, but necessary. Method declared in protcol might have // have been synthesized due to a property declared in the class which // uses the protocol. ObjCMethodDecl *MethodInClass = - IDecl->lookupInstanceMethod(Context, method->getSelector()); + IDecl->lookupInstanceMethod(method->getSelector()); if (!MethodInClass || !MethodInClass->isSynthesized()) WarnUndefinedMethod(ImpLoc, method, IncompleteImpl); } } // check unimplemented class methods for (ObjCProtocolDecl::classmeth_iterator - I = PDecl->classmeth_begin(Context), - E = PDecl->classmeth_end(Context); + I = PDecl->classmeth_begin(), E = PDecl->classmeth_end(); I != E; ++I) { ObjCMethodDecl *method = *I; if (method->getImplementationControl() != ObjCMethodDecl::Optional && !ClsMap.count(method->getSelector()) && - (!Super || !Super->lookupClassMethod(Context, method->getSelector()))) + (!Super || !Super->lookupClassMethod(method->getSelector()))) WarnUndefinedMethod(ImpLoc, method, IncompleteImpl); } // Check on this protocols's referenced protocols, recursively. @@ -937,8 +934,8 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet &InsMap, { // Check and see if instance methods in class interface have been // implemented in the implementation class. If so, their types match. - for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(Context), - E = CDecl->instmeth_end(Context); I != E; ++I) { + for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(), + E = CDecl->instmeth_end(); I != E; ++I) { if (InsMapSeen.count((*I)->getSelector())) continue; InsMapSeen.insert((*I)->getSelector()); @@ -950,9 +947,9 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet &InsMap, } else { ObjCMethodDecl *ImpMethodDecl = - IMPDecl->getInstanceMethod(Context, (*I)->getSelector()); + IMPDecl->getInstanceMethod((*I)->getSelector()); ObjCMethodDecl *IntfMethodDecl = - CDecl->getInstanceMethod(Context, (*I)->getSelector()); + CDecl->getInstanceMethod((*I)->getSelector()); assert(IntfMethodDecl && "IntfMethodDecl is null in ImplMethodsVsClassMethods"); // ImpMethodDecl may be null as in a @dynamic property. @@ -964,9 +961,7 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet &InsMap, // Check and see if class methods in class interface have been // implemented in the implementation class. If so, their types match. for (ObjCInterfaceDecl::classmeth_iterator - I = CDecl->classmeth_begin(Context), - E = CDecl->classmeth_end(Context); - I != E; ++I) { + I = CDecl->classmeth_begin(), E = CDecl->classmeth_end(); I != E; ++I) { if (ClsMapSeen.count((*I)->getSelector())) continue; ClsMapSeen.insert((*I)->getSelector()); @@ -975,10 +970,10 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet &InsMap, WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl); } else { - ObjCMethodDecl *ImpMethodDecl = - IMPDecl->getClassMethod(Context, (*I)->getSelector()); + ObjCMethodDecl *ImpMethodDecl = + IMPDecl->getClassMethod((*I)->getSelector()); ObjCMethodDecl *IntfMethodDecl = - CDecl->getClassMethod(Context, (*I)->getSelector()); + CDecl->getClassMethod((*I)->getSelector()); WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl); } } @@ -1003,24 +998,23 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl, // Check and see if instance methods in class interface have been // implemented in the implementation class. for (ObjCImplementationDecl::instmeth_iterator - I = IMPDecl->instmeth_begin(Context), - E = IMPDecl->instmeth_end(Context); I != E; ++I) + I = IMPDecl->instmeth_begin(), E = IMPDecl->instmeth_end(); I!=E; ++I) InsMap.insert((*I)->getSelector()); // Check and see if properties declared in the interface have either 1) // an implementation or 2) there is a @synthesize/@dynamic implementation // of the property in the @implementation. if (isa(CDecl)) - for (ObjCContainerDecl::prop_iterator P = CDecl->prop_begin(Context), - E = CDecl->prop_end(Context); P != E; ++P) { + for (ObjCContainerDecl::prop_iterator P = CDecl->prop_begin(), + E = CDecl->prop_end(); P != E; ++P) { ObjCPropertyDecl *Prop = (*P); if (Prop->isInvalidDecl()) continue; ObjCPropertyImplDecl *PI = 0; // Is there a matching propery synthesize/dynamic? for (ObjCImplDecl::propimpl_iterator - I = IMPDecl->propimpl_begin(Context), - EI = IMPDecl->propimpl_end(Context); I != EI; ++I) + I = IMPDecl->propimpl_begin(), + EI = IMPDecl->propimpl_end(); I != EI; ++I) if ((*I)->getPropertyDecl() == Prop) { PI = (*I); break; @@ -1046,8 +1040,8 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl, llvm::DenseSet ClsMap; for (ObjCImplementationDecl::classmeth_iterator - I = IMPDecl->classmeth_begin(Context), - E = IMPDecl->classmeth_end(Context); I != E; ++I) + I = IMPDecl->classmeth_begin(), + E = IMPDecl->classmeth_end(); I != E; ++I) ClsMap.insert((*I)->getSelector()); // Check for type conflict of methods declared in a class/protocol and @@ -1134,7 +1128,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc, &Interfaces[0], Interfaces.size()); - CurContext->addDecl(Context, CDecl); + CurContext->addDecl(CDecl); CheckObjCDeclScope(CDecl); return DeclPtrTy::make(CDecl); } @@ -1348,8 +1342,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *CD) { ObjCMethodDecl *GetterMethod, *SetterMethod; - GetterMethod = CD->getInstanceMethod(Context, property->getGetterName()); - SetterMethod = CD->getInstanceMethod(Context, property->getSetterName()); + GetterMethod = CD->getInstanceMethod(property->getGetterName()); + SetterMethod = CD->getInstanceMethod(property->getSetterName()); DiagnosePropertyAccessorMismatch(property, GetterMethod, property->getLocation()); @@ -1384,7 +1378,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCPropertyDecl::Optional) ? ObjCMethodDecl::Optional : ObjCMethodDecl::Required); - CD->addDecl(Context, GetterMethod); + CD->addDecl(GetterMethod); } else // A user declared getter will be synthesize when @synthesize of // the property with the same name is seen in the @implementation @@ -1415,7 +1409,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, VarDecl::None, 0); SetterMethod->setMethodParams(Context, &Argument, 1); - CD->addDecl(Context, SetterMethod); + CD->addDecl(SetterMethod); } else // A user declared setter will be synthesize when @synthesize of // the property with the same name is seen in the @implementation @@ -1481,7 +1475,7 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl, << Method->getDeclName(); Diag(PrevMethod->getLocation(), diag::note_previous_declaration); } else { - DC->addDecl(Context, Method); + DC->addDecl(Method); InsMap[Method->getSelector()] = Method; /// The following allows us to typecheck messages to "id". AddInstanceMethodToGlobalPool(Method); @@ -1498,7 +1492,7 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl, << Method->getDeclName(); Diag(PrevMethod->getLocation(), diag::note_previous_declaration); } else { - DC->addDecl(Context, Method); + DC->addDecl(Method); ClsMap[Method->getSelector()] = Method; /// The following allows us to typecheck messages to "Class". AddFactoryMethodToGlobalPool(Method); @@ -1524,8 +1518,8 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl, // ProcessPropertyDecl is responsible for diagnosing conflicts with any // user-defined setter/getter. It also synthesizes setter/getter methods // and adds them to the DeclContext and global method pools. - for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(Context), - E = CDecl->prop_end(Context); + for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(), + E = CDecl->prop_end(); I != E; ++I) ProcessPropertyDecl(*I, CDecl); CDecl->setAtEndLoc(AtEndLoc); @@ -1683,11 +1677,11 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( if (ObjCImplementationDecl *ImpDecl = dyn_cast(ClassDecl)) { if (MethodType == tok::minus) { - PrevMethod = ImpDecl->getInstanceMethod(Context, Sel); - ImpDecl->addInstanceMethod(Context, ObjCMethod); + PrevMethod = ImpDecl->getInstanceMethod(Sel); + ImpDecl->addInstanceMethod(ObjCMethod); } else { - PrevMethod = ImpDecl->getClassMethod(Context, Sel); - ImpDecl->addClassMethod(Context, ObjCMethod); + PrevMethod = ImpDecl->getClassMethod(Sel); + ImpDecl->addClassMethod(ObjCMethod); } if (AttrList) Diag(EndLoc, diag::warn_attribute_method_def); @@ -1695,11 +1689,11 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( else if (ObjCCategoryImplDecl *CatImpDecl = dyn_cast(ClassDecl)) { if (MethodType == tok::minus) { - PrevMethod = CatImpDecl->getInstanceMethod(Context, Sel); - CatImpDecl->addInstanceMethod(Context, ObjCMethod); + PrevMethod = CatImpDecl->getInstanceMethod(Sel); + CatImpDecl->addInstanceMethod(ObjCMethod); } else { - PrevMethod = CatImpDecl->getClassMethod(Context, Sel); - CatImpDecl->addClassMethod(Context, ObjCMethod); + PrevMethod = CatImpDecl->getClassMethod(Sel); + CatImpDecl->addClassMethod(ObjCMethod); } if (AttrList) Diag(EndLoc, diag::warn_attribute_method_def); @@ -1823,8 +1817,7 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, ObjCPropertyDecl *PIDecl = 0; IdentifierInfo *PropertyId = FD.D.getIdentifier(); for (ObjCInterfaceDecl::prop_iterator - I = CCPrimary->prop_begin(Context), - E = CCPrimary->prop_end(Context); + I = CCPrimary->prop_begin(), E = CCPrimary->prop_end(); I != E; ++I) if ((*I)->getIdentifier() == PropertyId) { PIDecl = *I; @@ -1870,7 +1863,7 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(), FD.D.getIdentifier(), T); - DC->addDecl(Context, PDecl); + DC->addDecl(PDecl); if (T->isArrayType() || T->isFunctionType()) { Diag(AtLoc, diag::err_property_type) << T; @@ -1951,7 +1944,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, "ActOnPropertyImplDecl - @implementation without @interface"); // Look for this property declaration in the @implementation's @interface - property = IDecl->FindPropertyDeclaration(Context, PropertyId); + property = IDecl->FindPropertyDeclaration(PropertyId); if (!property) { Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName(); return DeclPtrTy(); @@ -1975,7 +1968,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, if (!Category) return DeclPtrTy(); // Look for this property declaration in @implementation's category - property = Category->FindPropertyDeclaration(Context, PropertyId); + property = Category->FindPropertyDeclaration(PropertyId); if (!property) { Diag(PropertyLoc, diag::error_bad_category_property_decl) << Category->getDeclName(); @@ -1994,7 +1987,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, QualType PropType = Context.getCanonicalType(property->getType()); // Check that this is a previously declared 'ivar' in 'IDecl' interface ObjCInterfaceDecl *ClassDeclared; - Ivar = IDecl->lookupInstanceVariable(Context, PropertyIvar, ClassDeclared); + Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared); if (!Ivar) { DeclContext *EnclosingContext = cast_or_null(IDecl); assert(EnclosingContext && @@ -2004,7 +1997,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, ObjCIvarDecl::Public, (Expr *)0); Ivar->setLexicalDeclContext(IDecl); - IDecl->addDecl(Context, Ivar); + IDecl->addDecl(Ivar); property->setPropertyIvarDecl(Ivar); if (!getLangOptions().ObjCNonFragileABI) Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId; @@ -2071,7 +2064,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, if (IC) { if (Synthesize) if (ObjCPropertyImplDecl *PPIDecl = - IC->FindPropertyImplIvarDecl(Context, PropertyIvar)) { + IC->FindPropertyImplIvarDecl(PropertyIvar)) { Diag(PropertyLoc, diag::error_duplicate_ivar_use) << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() << PropertyIvar; @@ -2079,17 +2072,17 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, } if (ObjCPropertyImplDecl *PPIDecl - = IC->FindPropertyImplDecl(Context, PropertyId)) { + = IC->FindPropertyImplDecl(PropertyId)) { Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; Diag(PPIDecl->getLocation(), diag::note_previous_declaration); return DeclPtrTy(); } - IC->addPropertyImplementation(Context, PIDecl); + IC->addPropertyImplementation(PIDecl); } else { if (Synthesize) if (ObjCPropertyImplDecl *PPIDecl = - CatImplClass->FindPropertyImplIvarDecl(Context, PropertyIvar)) { + CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) { Diag(PropertyLoc, diag::error_duplicate_ivar_use) << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() << PropertyIvar; @@ -2097,12 +2090,12 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, } if (ObjCPropertyImplDecl *PPIDecl = - CatImplClass->FindPropertyImplDecl(Context, PropertyId)) { + CatImplClass->FindPropertyImplDecl(PropertyId)) { Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; Diag(PPIDecl->getLocation(), diag::note_previous_declaration); return DeclPtrTy(); } - CatImplClass->addPropertyImplementation(Context, PIDecl); + CatImplClass->addPropertyImplementation(PIDecl); } return DeclPtrTy::make(PIDecl); @@ -2154,7 +2147,7 @@ void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart, if (getLangOptions().CPlusPlus) PushOnScopeChains(cast(FD), S); else if (RecordDecl *Record = dyn_cast(TagD.getAs())) - Record->addDecl(Context, FD); + Record->addDecl(FD); } } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 383edeca07a0..a5e508396422 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -39,7 +39,7 @@ using namespace clang; /// referenced), false otherwise. bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) { // See if the decl is deprecated. - if (D->getAttr(Context)) { + if (D->getAttr()) { // Implementing deprecated stuff requires referencing deprecated // stuff. Don't warn if we are implementing a deprecated // construct. @@ -48,7 +48,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) { if (NamedDecl *ND = getCurFunctionOrMethodDecl()) { // If this reference happens *in* a deprecated function or method, don't // warn. - isSilenced = ND->getAttr(Context); + isSilenced = ND->getAttr(); // If this is an Objective-C method implementation, check to see if the // method was deprecated on the declaration, not the definition. @@ -58,10 +58,9 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) { if (ObjCImplementationDecl *Impl = dyn_cast(MD->getParent())) { - MD = Impl->getClassInterface()->getMethod(Context, - MD->getSelector(), + MD = Impl->getClassInterface()->getMethod(MD->getSelector(), MD->isInstanceMethod()); - isSilenced |= MD && MD->getAttr(Context); + isSilenced |= MD && MD->getAttr(); } } } @@ -80,7 +79,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) { } // See if the decl is unavailable - if (D->getAttr(Context)) { + if (D->getAttr()) { Diag(Loc, diag::warn_unavailable) << D->getDeclName(); Diag(D->getLocation(), diag::note_unavailable_here) << 0; } @@ -95,7 +94,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) { void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, Expr **Args, unsigned NumArgs) { - const SentinelAttr *attr = D->getAttr(Context); + const SentinelAttr *attr = D->getAttr(); if (!attr) return; int sentinelPos = attr->getSentinel(); @@ -673,8 +672,8 @@ static Decl *getObjectForAnonymousRecordDecl(ASTContext &Context, // operation rather than a slow walk through DeclContext's vector (which // itself will be eliminated). DeclGroups might make this even better. DeclContext *Ctx = Record->getDeclContext(); - for (DeclContext::decl_iterator D = Ctx->decls_begin(Context), - DEnd = Ctx->decls_end(Context); + for (DeclContext::decl_iterator D = Ctx->decls_begin(), + DEnd = Ctx->decls_end(); D != DEnd; ++D) { if (*D == Record) { // The object for the anonymous struct/union directly @@ -877,8 +876,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, if (D == 0 || D->isDefinedOutsideFunctionOrMethod()) { ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface(); ObjCInterfaceDecl *ClassDeclared; - if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(Context, II, - ClassDeclared)) { + if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) { // Check if referencing a field with __attribute__((deprecated)). if (DiagnoseUseOfDecl(IV, Loc)) return ExprError(); @@ -915,8 +913,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // We should warn if a local variable hides an ivar. ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface(); ObjCInterfaceDecl *ClassDeclared; - if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(Context, II, - ClassDeclared)) { + if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) { if (IV->getAccessControl() != ObjCIvarDecl::Private || IFace == ClassDeclared) Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName(); @@ -973,7 +970,64 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, return ExprError(Diag(Loc, diag::err_undeclared_var_use) << Name); } } + + if (VarDecl *Var = dyn_cast(D)) { + // Warn about constructs like: + // if (void *X = foo()) { ... } else { X }. + // In the else block, the pointer is always false. + + // FIXME: In a template instantiation, we don't have scope + // information to check this property. + if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) { + Scope *CheckS = S; + while (CheckS) { + if (CheckS->isWithinElse() && + CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) { + if (Var->getType()->isBooleanType()) + ExprError(Diag(Loc, diag::warn_value_always_false) + << Var->getDeclName()); + else + ExprError(Diag(Loc, diag::warn_value_always_zero) + << Var->getDeclName()); + break; + } + + // Move up one more control parent to check again. + CheckS = CheckS->getControlParent(); + if (CheckS) + CheckS = CheckS->getParent(); + } + } + } else if (FunctionDecl *Func = dyn_cast(D)) { + if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) { + // C99 DR 316 says that, if a function type comes from a + // function definition (without a prototype), that type is only + // used for checking compatibility. Therefore, when referencing + // the function, we pretend that we don't have the full function + // type. + if (DiagnoseUseOfDecl(Func, Loc)) + return ExprError(); + + QualType T = Func->getType(); + QualType NoProtoType = T; + if (const FunctionProtoType *Proto = T->getAsFunctionProtoType()) + NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType()); + return BuildDeclRefExpr(Func, NoProtoType, Loc, false, false, SS); + } + } + + return BuildDeclarationNameExpr(Loc, D, HasTrailingLParen, SS, isAddressOfOperand); +} +/// \brief Complete semantic analysis for a reference to the given declaration. +Sema::OwningExprResult +Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D, + bool HasTrailingLParen, + const CXXScopeSpec *SS, + bool isAddressOfOperand) { + assert(D && "Cannot refer to a NULL declaration"); + DeclarationName Name = D->getDeclName(); + // If this is an expression of the form &Class::member, don't build an // implicit member ref, because we want a pointer to the member in general, // not any specific instance's member. @@ -1097,51 +1151,11 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // this check when we're going to perform argument-dependent lookup // on this function name, because this might not be the function // that overload resolution actually selects. + bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) && + HasTrailingLParen; if (!(ADL && isa(VD)) && DiagnoseUseOfDecl(VD, Loc)) return ExprError(); - if (VarDecl *Var = dyn_cast(VD)) { - // Warn about constructs like: - // if (void *X = foo()) { ... } else { X }. - // In the else block, the pointer is always false. - - // FIXME: In a template instantiation, we don't have scope - // information to check this property. - if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) { - Scope *CheckS = S; - while (CheckS) { - if (CheckS->isWithinElse() && - CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) { - if (Var->getType()->isBooleanType()) - ExprError(Diag(Loc, diag::warn_value_always_false) - << Var->getDeclName()); - else - ExprError(Diag(Loc, diag::warn_value_always_zero) - << Var->getDeclName()); - break; - } - - // Move up one more control parent to check again. - CheckS = CheckS->getControlParent(); - if (CheckS) - CheckS = CheckS->getParent(); - } - } - } else if (FunctionDecl *Func = dyn_cast(VD)) { - if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) { - // C99 DR 316 says that, if a function type comes from a - // function definition (without a prototype), that type is only - // used for checking compatibility. Therefore, when referencing - // the function, we pretend that we don't have the full function - // type. - QualType T = Func->getType(); - QualType NoProtoType = T; - if (const FunctionProtoType *Proto = T->getAsFunctionProtoType()) - NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType()); - return BuildDeclRefExpr(VD, NoProtoType, Loc, false, false, SS); - } - } - // Only create DeclRefExpr's for valid Decl's. if (VD->isInvalidDecl()) return ExprError(); @@ -1158,7 +1172,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, MarkDeclarationReferenced(Loc, VD); QualType ExprTy = VD->getType().getNonReferenceType(); // The BlocksAttr indicates the variable is bound by-reference. - if (VD->getAttr(Context)) + if (VD->getAttr()) return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true)); // This is to record that a 'const' was actually synthesize and added. bool constAdded = !ExprTy.isConstQualified(); @@ -1310,8 +1324,8 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) { // isExact will be set by GetFloatValue(). bool isExact = false; - Res = new (Context) FloatingLiteral(Literal.GetFloatValue(Format, &isExact), - &isExact, Ty, Tok.getLocation()); + llvm::APFloat Val = Literal.GetFloatValue(Format, &isExact); + Res = new (Context) FloatingLiteral(Val, isExact, Ty, Tok.getLocation()); } else if (!Literal.isIntegerLiteral()) { return ExprError(); @@ -1989,9 +2003,9 @@ static Decl *FindGetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl, const Selector &Sel, ASTContext &Context) { - if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(Context, &Member)) + if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(&Member)) return PD; - if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Context, Sel)) + if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel)) return OMD; for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(), @@ -2011,12 +2025,12 @@ static Decl *FindGetterNameDecl(const ObjCObjectPointerType *QIdTy, Decl *GDecl = 0; for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(), E = QIdTy->qual_end(); I != E; ++I) { - if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Context, &Member)) { + if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) { GDecl = PD; break; } // Also must look for a getter name which uses property syntax. - if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Context, Sel)) { + if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) { GDecl = OMD; break; } @@ -2042,7 +2056,7 @@ ObjCMethodDecl *Sema::FindMethodInNestedImplementations( ObjCMethodDecl *Method = 0; if (ObjCImplementationDecl *ImpDecl = LookupObjCImplementation(IFace->getIdentifier())) - Method = ImpDecl->getInstanceMethod(Context, Sel); + Method = ImpDecl->getInstanceMethod(Sel); if (!Method && IFace->getSuperClass()) return FindMethodInNestedImplementations(IFace->getSuperClass(), Sel); @@ -2201,8 +2215,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, // (*Obj).ivar. if (const ObjCInterfaceType *IFTy = BaseType->getAsObjCInterfaceType()) { ObjCInterfaceDecl *ClassDeclared; - if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(Context, - &Member, + if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(&Member, ClassDeclared)) { // If the decl being referenced had an error, return an error for this // sub-expr without emitting another error, in order to avoid cascading @@ -2262,14 +2275,13 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, ObjCInterfaceDecl *IFace = IFTy->getDecl(); // Search for a declared property first. - if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Context, - &Member)) { + if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member)) { // Check whether we can reference this property. if (DiagnoseUseOfDecl(PD, MemberLoc)) return ExprError(); QualType ResTy = PD->getType(); Selector Sel = PP.getSelectorTable().getNullarySelector(&Member); - ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Context, Sel); + ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel); if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc)) ResTy = Getter->getResultType(); return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy, @@ -2279,8 +2291,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, // Check protocols on qualified interfaces. for (ObjCInterfaceType::qual_iterator I = IFTy->qual_begin(), E = IFTy->qual_end(); I != E; ++I) - if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Context, - &Member)) { + if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) { // Check whether we can reference this property. if (DiagnoseUseOfDecl(PD, MemberLoc)) return ExprError(); @@ -2296,7 +2307,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, // shared with the code in ActOnInstanceMessage. Selector Sel = PP.getSelectorTable().getNullarySelector(&Member); - ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Context, Sel); + ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel); // If this reference is in an @implementation, check for 'private' methods. if (!Getter) @@ -2306,7 +2317,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, if (!Getter) { for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Getter; i++) { if (ObjCCategoryImpls[i]->getClassInterface() == IFace) - Getter = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel); + Getter = ObjCCategoryImpls[i]->getInstanceMethod(Sel); } } if (Getter) { @@ -2319,7 +2330,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, Selector SetterSel = SelectorTable::constructSetterName(PP.getIdentifierTable(), PP.getSelectorTable(), &Member); - ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(Context, SetterSel); + ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel); if (!Setter) { // If this reference is in an @implementation, also check for 'private' // methods. @@ -2329,7 +2340,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, if (!Setter) { for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) { if (ObjCCategoryImpls[i]->getClassInterface() == IFace) - Setter = ObjCCategoryImpls[i]->getInstanceMethod(Context, SetterSel); + Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel); } } @@ -2390,7 +2401,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, ObjCInterfaceDecl *IFace = MD->getClassInterface(); ObjCMethodDecl *Getter; // FIXME: need to also look locally in the implementation. - if ((Getter = IFace->lookupClassMethod(Context, Sel))) { + if ((Getter = IFace->lookupClassMethod(Sel))) { // Check the use of this method. if (DiagnoseUseOfDecl(Getter, MemberLoc)) return ExprError(); @@ -2400,7 +2411,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, Selector SetterSel = SelectorTable::constructSetterName(PP.getIdentifierTable(), PP.getSelectorTable(), &Member); - ObjCMethodDecl *Setter = IFace->lookupClassMethod(Context, SetterSel); + ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel); if (!Setter) { // If this reference is in an @implementation, also check for 'private' // methods. @@ -2410,7 +2421,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, if (!Setter) { for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) { if (ObjCCategoryImpls[i]->getClassInterface() == IFace) - Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel); + Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel); } } @@ -2624,9 +2635,13 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, } // If we're directly calling a function, get the appropriate declaration. - DeclRefExpr *DRExpr = NULL; + // Also, in C++, keep track of whether we should perform argument-dependent + // lookup and whether there were any explicitly-specified template arguments. Expr *FnExpr = Fn; bool ADL = true; + bool HasExplicitTemplateArgs = 0; + const TemplateArgument *ExplicitTemplateArgs = 0; + unsigned NumExplicitTemplateArgs = 0; while (true) { if (ImplicitCastExpr *IcExpr = dyn_cast(FnExpr)) FnExpr = IcExpr->getSubExpr(); @@ -2639,14 +2654,41 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, cast(FnExpr)->getOpcode() == UnaryOperator::AddrOf) { FnExpr = cast(FnExpr)->getSubExpr(); - } else if ((DRExpr = dyn_cast(FnExpr))) { + } else if (DeclRefExpr *DRExpr = dyn_cast(FnExpr)) { // Qualified names disable ADL (C++0x [basic.lookup.argdep]p1). ADL &= !isa(DRExpr); + NDecl = dyn_cast(DRExpr->getDecl()); break; } else if (UnresolvedFunctionNameExpr *DepName = dyn_cast(FnExpr)) { UnqualifiedName = DepName->getName(); break; + } else if (TemplateIdRefExpr *TemplateIdRef + = dyn_cast(FnExpr)) { + NDecl = TemplateIdRef->getTemplateName().getAsTemplateDecl(); + HasExplicitTemplateArgs = true; + ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs(); + NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs(); + + // C++ [temp.arg.explicit]p6: + // [Note: For simple function names, argument dependent lookup (3.4.2) + // applies even when the function name is not visible within the + // scope of the call. This is because the call still has the syntactic + // form of a function call (3.4.1). But when a function template with + // explicit template arguments is used, the call does not have the + // correct syntactic form unless there is a function template with + // that name visible at the point of the call. If no such name is + // visible, the call is not syntactically well-formed and + // argument-dependent lookup does not apply. If some such name is + // visible, argument dependent lookup applies and additional function + // templates may be found in other namespaces. + // + // The summary of this paragraph is that, if we get to this point and the + // template-id was not a qualified name, then argument-dependent lookup + // is still possible. + if (TemplateIdRef->getQualifier()) + ADL = false; + break; } else { // Any kind of name that does not refer to a declaration (or // set of declarations) disables ADL (C++0x [basic.lookup.argdep]p3). @@ -2657,14 +2699,13 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, OverloadedFunctionDecl *Ovl = 0; FunctionTemplateDecl *FunctionTemplate = 0; - if (DRExpr) { - FDecl = dyn_cast(DRExpr->getDecl()); - if ((FunctionTemplate = dyn_cast(DRExpr->getDecl()))) + if (NDecl) { + FDecl = dyn_cast(NDecl); + if ((FunctionTemplate = dyn_cast(NDecl))) FDecl = FunctionTemplate->getTemplatedDecl(); else - FDecl = dyn_cast(DRExpr->getDecl()); - Ovl = dyn_cast(DRExpr->getDecl()); - NDecl = dyn_cast(DRExpr->getDecl()); + FDecl = dyn_cast(NDecl); + Ovl = dyn_cast(NDecl); } if (Ovl || FunctionTemplate || @@ -2678,16 +2719,19 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, ADL = false; if (Ovl || FunctionTemplate || ADL) { - FDecl = ResolveOverloadedCallFn(Fn, DRExpr? DRExpr->getDecl() : 0, - UnqualifiedName, LParenLoc, Args, - NumArgs, CommaLocs, RParenLoc, ADL); + FDecl = ResolveOverloadedCallFn(Fn, NDecl, UnqualifiedName, + HasExplicitTemplateArgs, + ExplicitTemplateArgs, + NumExplicitTemplateArgs, + LParenLoc, Args, NumArgs, CommaLocs, + RParenLoc, ADL); if (!FDecl) return ExprError(); // Update Fn to refer to the actual function selected. Expr *NewFn = 0; if (QualifiedDeclRefExpr *QDRExpr - = dyn_cast_or_null(DRExpr)) + = dyn_cast(FnExpr)) NewFn = new (Context) QualifiedDeclRefExpr(FDecl, FDecl->getType(), QDRExpr->getLocation(), false, false, @@ -2750,7 +2794,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, // Check if we have too few/too many template arguments, based // on our knowledge of the function definition. const FunctionDecl *Def = 0; - if (FDecl->getBody(Context, Def) && NumArgs != Def->param_size()) { + if (FDecl->getBody(Def) && NumArgs != Def->param_size()) { const FunctionProtoType *Proto = Def->getType()->getAsFunctionProtoType(); if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size())) { @@ -2860,7 +2904,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr) { // GCC cast to union extension RecordDecl *RD = castType->getAsRecordType()->getDecl(); RecordDecl::field_iterator Field, FieldEnd; - for (Field = RD->field_begin(Context), FieldEnd = RD->field_end(Context); + for (Field = RD->field_begin(), FieldEnd = RD->field_end(); Field != FieldEnd; ++Field) { if (Context.getCanonicalType(Field->getType()).getUnqualifiedType() == Context.getCanonicalType(castExpr->getType()).getUnqualifiedType()) { @@ -2931,19 +2975,8 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty) { bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) { assert(DestTy->isExtVectorType() && "Not an extended vector type!"); - // If SrcTy is also an ExtVectorType, the types must be identical unless - // lax vector conversions is enabled. - if (SrcTy->isExtVectorType()) { - if (getLangOptions().LaxVectorConversions && - Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy)) - return false; - if (DestTy != SrcTy) - return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors) - << DestTy << SrcTy << R; - return false; - } - - // If SrcTy is a VectorType, then only the total size must match. + // If SrcTy is a VectorType, the total size must match to explicitly cast to + // an ExtVectorType. if (SrcTy->isVectorType()) { if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy)) return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors) @@ -2951,9 +2984,13 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) { return false; } - // All scalar -> ext vector "c-style" casts are legal; the appropriate + // All non-pointer scalars can be cast to ExtVector type. The appropriate // conversion will take place first from scalar to elt type, and then // splat from elt type to vector. + if (SrcTy->isPointerType()) + return Diag(R.getBegin(), + diag::err_invalid_conversion_between_vector_and_scalar) + << DestTy << SrcTy << R; return false; } @@ -3042,24 +3079,133 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, ImpCastExprToType(LHS, RHSTy); // promote the null to a pointer. return RHSTy; } + // Handle block pointer types. + if (LHSTy->isBlockPointerType() || RHSTy->isBlockPointerType()) { + if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) { + if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) { + QualType destType = Context.getPointerType(Context.VoidTy); + ImpCastExprToType(LHS, destType); + ImpCastExprToType(RHS, destType); + return destType; + } + Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) + << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange(); + return QualType(); + } + // We have 2 block pointer types. + if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) { + // Two identical block pointer types are always compatible. + return LHSTy; + } + // The block pointer types aren't identical, continue checking. + QualType lhptee = LHSTy->getAsBlockPointerType()->getPointeeType(); + QualType rhptee = RHSTy->getAsBlockPointerType()->getPointeeType(); - const PointerType *LHSPT = LHSTy->getAsPointerType(); - const PointerType *RHSPT = RHSTy->getAsPointerType(); - const BlockPointerType *LHSBPT = LHSTy->getAsBlockPointerType(); - const BlockPointerType *RHSBPT = RHSTy->getAsBlockPointerType(); + if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(), + rhptee.getUnqualifiedType())) { + Diag(QuestionLoc, diag::warn_typecheck_cond_incompatible_pointers) + << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange(); + // In this situation, we assume void* type. No especially good + // reason, but this is what gcc does, and we do have to pick + // to get a consistent AST. + QualType incompatTy = Context.getPointerType(Context.VoidTy); + ImpCastExprToType(LHS, incompatTy); + ImpCastExprToType(RHS, incompatTy); + return incompatTy; + } + // The block pointer types are compatible. + ImpCastExprToType(LHS, LHSTy); + ImpCastExprToType(RHS, LHSTy); + return LHSTy; + } + // Need to handle "id" explicitly. Unlike "id", whose canonical type + // evaluates to "struct objc_object *" (and is handled above when comparing + // id with statically typed objects). + if (LHSTy->isObjCQualifiedIdType() || RHSTy->isObjCQualifiedIdType()) { + // GCC allows qualified id and any Objective-C type to devolve to + // id. Currently localizing to here until clear this should be + // part of ObjCQualifiedIdTypesAreCompatible. + if (ObjCQualifiedIdTypesAreCompatible(LHSTy, RHSTy, true) || + (LHSTy->isObjCQualifiedIdType() && + Context.isObjCObjectPointerType(RHSTy)) || + (RHSTy->isObjCQualifiedIdType() && + Context.isObjCObjectPointerType(LHSTy))) { + // FIXME: This is not the correct composite type. This only happens to + // work because id can more or less be used anywhere, however this may + // change the type of method sends. - // Handle the case where both operands are pointers before we handle null - // pointer constants in case both operands are null pointer constants. - if ((LHSPT || LHSBPT) && (RHSPT || RHSBPT)) { // C99 6.5.15p3,6 + // FIXME: gcc adds some type-checking of the arguments and emits + // (confusing) incompatible comparison warnings in some + // cases. Investigate. + QualType compositeType = Context.getObjCIdType(); + ImpCastExprToType(LHS, compositeType); + ImpCastExprToType(RHS, compositeType); + return compositeType; + } + } + // Check constraints for Objective-C object pointers types. + if (Context.isObjCObjectPointerType(LHSTy) && + Context.isObjCObjectPointerType(RHSTy)) { + + if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) { + // Two identical object pointer types are always compatible. + return LHSTy; + } + // No need to check for block pointer types or qualified id types (they + // were handled above). + assert((LHSTy->isPointerType() && RHSTy->isPointerType()) && + "Sema::CheckConditionalOperands(): Unexpected type"); + QualType lhptee = LHSTy->getAsPointerType()->getPointeeType(); + QualType rhptee = RHSTy->getAsPointerType()->getPointeeType(); + + QualType compositeType = LHSTy; + + // If both operands are interfaces and either operand can be + // assigned to the other, use that type as the composite + // type. This allows + // xxx ? (A*) a : (B*) b + // where B is a subclass of A. + // + // Additionally, as for assignment, if either type is 'id' + // allow silent coercion. Finally, if the types are + // incompatible then make sure to use 'id' as the composite + // type so the result is acceptable for sending messages to. + + // FIXME: Consider unifying with 'areComparableObjCPointerTypes'. + // It could return the composite type. + const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType(); + const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType(); + if (LHSIface && RHSIface && + Context.canAssignObjCInterfaces(LHSIface, RHSIface)) { + compositeType = LHSTy; + } else if (LHSIface && RHSIface && + Context.canAssignObjCInterfaces(RHSIface, LHSIface)) { + compositeType = RHSTy; + } else if (Context.isObjCIdStructType(lhptee) || + Context.isObjCIdStructType(rhptee)) { + compositeType = Context.getObjCIdType(); + } else { + Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands) + << LHSTy << RHSTy + << LHS->getSourceRange() << RHS->getSourceRange(); + QualType incompatTy = Context.getObjCIdType(); + ImpCastExprToType(LHS, incompatTy); + ImpCastExprToType(RHS, incompatTy); + return incompatTy; + } + // The object pointer types are compatible. + ImpCastExprToType(LHS, compositeType); + ImpCastExprToType(RHS, compositeType); + return compositeType; + } + // Check constraints for C object pointers types (C99 6.5.15p3,6). + if (LHSTy->isPointerType() && RHSTy->isPointerType()) { // get the "pointed to" types - QualType lhptee = (LHSPT ? LHSPT->getPointeeType() - : LHSBPT->getPointeeType()); - QualType rhptee = (RHSPT ? RHSPT->getPointeeType() - : RHSBPT->getPointeeType()); + QualType lhptee = LHSTy->getAsPointerType()->getPointeeType(); + QualType rhptee = RHSTy->getAsPointerType()->getPointeeType(); // ignore qualifiers on void (C99 6.5.15p3, clause 6) - if (lhptee->isVoidType() - && (RHSBPT || rhptee->isIncompleteOrObjectType())) { + if (lhptee->isVoidType() && rhptee->isIncompleteOrObjectType()) { // Figure out necessary qualifiers (C99 6.5.15p6) QualType destPointee=lhptee.getQualifiedType(rhptee.getCVRQualifiers()); QualType destType = Context.getPointerType(destPointee); @@ -3067,8 +3213,7 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, ImpCastExprToType(RHS, destType); // promote to void* return destType; } - if (rhptee->isVoidType() - && (LHSBPT || lhptee->isIncompleteOrObjectType())) { + if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) { QualType destPointee=rhptee.getQualifiedType(lhptee.getCVRQualifiers()); QualType destType = Context.getPointerType(destPointee); ImpCastExprToType(LHS, destType); // add qualifiers if necessary @@ -3076,62 +3221,12 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, return destType; } - bool sameKind = (LHSPT && RHSPT) || (LHSBPT && RHSBPT); - if (sameKind - && Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) { + if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) { // Two identical pointer types are always compatible. return LHSTy; } - - QualType compositeType = LHSTy; - - // If either type is an Objective-C object type then check - // compatibility according to Objective-C. - if (Context.isObjCObjectPointerType(LHSTy) || - Context.isObjCObjectPointerType(RHSTy)) { - // If both operands are interfaces and either operand can be - // assigned to the other, use that type as the composite - // type. This allows - // xxx ? (A*) a : (B*) b - // where B is a subclass of A. - // - // Additionally, as for assignment, if either type is 'id' - // allow silent coercion. Finally, if the types are - // incompatible then make sure to use 'id' as the composite - // type so the result is acceptable for sending messages to. - - // FIXME: Consider unifying with 'areComparableObjCPointerTypes'. - // It could return the composite type. - const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType(); - const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType(); - if (LHSIface && RHSIface && - Context.canAssignObjCInterfaces(LHSIface, RHSIface)) { - compositeType = LHSTy; - } else if (LHSIface && RHSIface && - Context.canAssignObjCInterfaces(RHSIface, LHSIface)) { - compositeType = RHSTy; - } else if (Context.isObjCIdStructType(lhptee) || - Context.isObjCIdStructType(rhptee)) { - compositeType = Context.getObjCIdType(); - } else if (LHSBPT || RHSBPT) { - if (!sameKind - || !Context.typesAreCompatible(lhptee.getUnqualifiedType(), - rhptee.getUnqualifiedType())) - Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) - << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange(); - return QualType(); - } else { - Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands) - << LHSTy << RHSTy - << LHS->getSourceRange() << RHS->getSourceRange(); - QualType incompatTy = Context.getObjCIdType(); - ImpCastExprToType(LHS, incompatTy); - ImpCastExprToType(RHS, incompatTy); - return incompatTy; - } - } else if (!sameKind - || !Context.typesAreCompatible(lhptee.getUnqualifiedType(), - rhptee.getUnqualifiedType())) { + if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(), + rhptee.getUnqualifiedType())) { Diag(QuestionLoc, diag::warn_typecheck_cond_incompatible_pointers) << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange(); // In this situation, we assume void* type. No especially good @@ -3149,11 +3244,11 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, // type. // FIXME: Need to calculate the composite type. // FIXME: Need to add qualifiers - ImpCastExprToType(LHS, compositeType); - ImpCastExprToType(RHS, compositeType); - return compositeType; + ImpCastExprToType(LHS, LHSTy); + ImpCastExprToType(RHS, LHSTy); + return LHSTy; } - + // GCC compatibility: soften pointer/integer mismatch. if (RHSTy->isPointerType() && LHSTy->isIntegerType()) { Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch) @@ -3168,32 +3263,6 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, return LHSTy; } - // Need to handle "id" explicitly. Unlike "id", whose canonical type - // evaluates to "struct objc_object *" (and is handled above when comparing - // id with statically typed objects). - if (LHSTy->isObjCQualifiedIdType() || RHSTy->isObjCQualifiedIdType()) { - // GCC allows qualified id and any Objective-C type to devolve to - // id. Currently localizing to here until clear this should be - // part of ObjCQualifiedIdTypesAreCompatible. - if (ObjCQualifiedIdTypesAreCompatible(LHSTy, RHSTy, true) || - (LHSTy->isObjCQualifiedIdType() && - Context.isObjCObjectPointerType(RHSTy)) || - (RHSTy->isObjCQualifiedIdType() && - Context.isObjCObjectPointerType(LHSTy))) { - // FIXME: This is not the correct composite type. This only happens to - // work because id can more or less be used anywhere, however this may - // change the type of method sends. - - // FIXME: gcc adds some type-checking of the arguments and emits - // (confusing) incompatible comparison warnings in some - // cases. Investigate. - QualType compositeType = Context.getObjCIdType(); - ImpCastExprToType(LHS, compositeType); - ImpCastExprToType(RHS, compositeType); - return compositeType; - } - } - // Otherwise, the operands are not compatible. Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange(); @@ -3385,12 +3454,16 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { return IncompatibleObjCQualifiedId; } + // Allow scalar to ExtVector assignments, and assignments of an ExtVector type + // to the same ExtVector type. + if (lhsType->isExtVectorType()) { + if (rhsType->isExtVectorType()) + return lhsType == rhsType ? Compatible : Incompatible; + if (!rhsType->isVectorType() && rhsType->isArithmeticType()) + return Compatible; + } + if (lhsType->isVectorType() || rhsType->isVectorType()) { - // For ExtVector, allow vector splats; float -> - if (const ExtVectorType *LV = lhsType->getAsExtVectorType()) - if (LV->getElementType() == rhsType) - return Compatible; - // If we are allowing lax vector conversions, and LHS and RHS are both // vectors, the total size only needs to be the same. This is a bitcast; // no bits are changed but the result type is different. @@ -3492,15 +3565,15 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Expr *&rExpr) { // If the ArgType is a Union type, we want to handle a potential // transparent_union GCC extension. const RecordType *UT = ArgType->getAsUnionType(); - if (!UT || !UT->getDecl()->hasAttr(Context)) + if (!UT || !UT->getDecl()->hasAttr()) return Incompatible; // The field to initialize within the transparent union. RecordDecl *UD = UT->getDecl(); FieldDecl *InitField = 0; // It's compatible if the expression matches any of the fields. - for (RecordDecl::field_iterator it = UD->field_begin(Context), - itend = UD->field_end(Context); + for (RecordDecl::field_iterator it = UD->field_begin(), + itend = UD->field_end(); it != itend; ++it) { if (it->getType()->isPointerType()) { // If the transparent union contains a pointer type, we allow: @@ -3617,33 +3690,36 @@ inline QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, } } - // If the lhs is an extended vector and the rhs is a scalar of the same type - // or a literal, promote the rhs to the vector type. - if (const ExtVectorType *V = lhsType->getAsExtVectorType()) { - QualType eltType = V->getElementType(); - - if ((eltType->getAsBuiltinType() == rhsType->getAsBuiltinType()) || - (eltType->isIntegerType() && isa(rex)) || - (eltType->isFloatingType() && isa(rex))) { - ImpCastExprToType(rex, lhsType); - return lhsType; - } + // Canonicalize the ExtVector to the LHS, remember if we swapped so we can + // swap back (so that we don't reverse the inputs to a subtract, for instance. + bool swapped = false; + if (rhsType->isExtVectorType()) { + swapped = true; + std::swap(rex, lex); + std::swap(rhsType, lhsType); } - - // If the rhs is an extended vector and the lhs is a scalar of the same type, - // promote the lhs to the vector type. - if (const ExtVectorType *V = rhsType->getAsExtVectorType()) { - QualType eltType = V->getElementType(); - - if ((eltType->getAsBuiltinType() == lhsType->getAsBuiltinType()) || - (eltType->isIntegerType() && isa(lex)) || - (eltType->isFloatingType() && isa(lex))) { - ImpCastExprToType(lex, rhsType); - return rhsType; + + // Handle the case of an ext vector and scalar. + if (const ExtVectorType *LV = lhsType->getAsExtVectorType()) { + QualType EltTy = LV->getElementType(); + if (EltTy->isIntegralType() && rhsType->isIntegralType()) { + if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) { + ImpCastExprToType(rex, lhsType); + if (swapped) std::swap(rex, lex); + return lhsType; + } + } + if (EltTy->isRealFloatingType() && rhsType->isScalarType() && + rhsType->isRealFloatingType()) { + if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) { + ImpCastExprToType(rex, lhsType); + if (swapped) std::swap(rex, lex); + return lhsType; + } } } - - // You cannot convert between vector values of different size. + + // Vectors of different size or scalar and non-ext-vector are errors. Diag(Loc, diag::err_typecheck_vector_not_convertable) << lex->getType() << rex->getType() << lex->getSourceRange() << rex->getSourceRange(); @@ -4034,6 +4110,17 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, QualType RCanPointeeTy = Context.getCanonicalType(rType->getAsPointerType()->getPointeeType()); + if (rType->isFunctionPointerType() || lType->isFunctionPointerType()) { + if (isRelational) { + Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers) + << lType << rType << lex->getSourceRange() << rex->getSourceRange(); + } + } + if (((!LHSIsNull || isRelational) && LCanPointeeTy->isVoidType()) != + ((!RHSIsNull || isRelational) && RCanPointeeTy->isVoidType())) { + Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers) + << lType << rType << lex->getSourceRange() << rex->getSourceRange(); + } // Simple check: if the pointee types are identical, we're done. if (LCanPointeeTy == RCanPointeeTy) return ResultTy; @@ -4146,7 +4233,10 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, } if ((lType->isPointerType() || lType->isObjCQualifiedIdType()) && rType->isIntegerType()) { - if (!RHSIsNull) + if (isRelational) + Diag(Loc, diag::ext_typecheck_ordered_comparison_of_pointer_integer) + << lType << rType << lex->getSourceRange() << rex->getSourceRange(); + else if (!RHSIsNull) Diag(Loc, diag::ext_typecheck_comparison_of_pointer_integer) << lType << rType << lex->getSourceRange() << rex->getSourceRange(); ImpCastExprToType(rex, lType); // promote the integer to pointer @@ -4154,7 +4244,10 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, } if (lType->isIntegerType() && (rType->isPointerType() || rType->isObjCQualifiedIdType())) { - if (!LHSIsNull) + if (isRelational) + Diag(Loc, diag::ext_typecheck_ordered_comparison_of_pointer_integer) + << lType << rType << lex->getSourceRange() << rex->getSourceRange(); + else if (!LHSIsNull) Diag(Loc, diag::ext_typecheck_comparison_of_pointer_integer) << lType << rType << lex->getSourceRange() << rex->getSourceRange(); ImpCastExprToType(lex, rType); // promote the integer to pointer @@ -5226,7 +5319,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { CurBlock->hasPrototype = true; CurBlock->isVariadic = false; // Check for a valid sentinel attribute on this block. - if (CurBlock->TheDecl->getAttr(Context)) { + if (CurBlock->TheDecl->getAttr()) { Diag(ParamInfo.getAttributes()->getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; // FIXME: remove the attribute. @@ -5275,7 +5368,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { // Check for a valid sentinel attribute on this block. if (!CurBlock->isVariadic && - CurBlock->TheDecl->getAttr(Context)) { + CurBlock->TheDecl->getAttr()) { Diag(ParamInfo.getAttributes()->getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; // FIXME: remove the attribute. @@ -5607,13 +5700,13 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { if (FunctionDecl *Function = dyn_cast(D)) { // Implicit instantiation of function templates and member functions of // class templates. - if (!Function->getBody(Context)) { + if (!Function->getBody()) { // FIXME: distinguish between implicit instantiations of function // templates and explicit specializations (the latter don't get // instantiated, naturally). if (Function->getInstantiatedFromMemberFunction() || Function->getPrimaryTemplate()) - PendingImplicitInstantiations.push(std::make_pair(Function, Loc)); + PendingImplicitInstantiations.push_back(std::make_pair(Function, Loc)); } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index bc8fc4eae502..7afa5941dad9 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -552,7 +552,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, bool AllowMissing, FunctionDecl *&Operator) { DeclContext::lookup_iterator Alloc, AllocEnd; - llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Context, Name); + llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Name); if (Alloc == AllocEnd) { if (AllowMissing) return false; @@ -657,7 +657,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, // Check if this function is already declared. { DeclContext::lookup_iterator Alloc, AllocEnd; - for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Context, Name); + for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Name); Alloc != AllocEnd; ++Alloc) { // FIXME: Do we need to check for default arguments here? FunctionDecl *Func = cast(*Alloc); @@ -680,7 +680,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, // FIXME: Also add this declaration to the IdentifierResolver, but // make sure it is at the end of the chain to coincide with the // global scope. - ((DeclContext *)TUScope->getEntity())->addDecl(Context, Alloc); + ((DeclContext *)TUScope->getEntity())->addDecl(Alloc); } /// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in: @@ -1567,7 +1567,7 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) { CXXTemporary *Temp = CXXTemporary::Create(Context, RD->getDestructor(Context)); ExprTemporaries.push_back(Temp); - MarcDestructorReferenced(E->getExprLoc(), E->getType()); + MarkDestructorReferenced(E->getExprLoc(), E->getType()); // FIXME: Add the temporary to the temporaries vector. return Owned(CXXBindTemporaryExpr::Create(Context, Temp, E)); } diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index f1869f903719..7bb6b44c39cf 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -243,13 +243,13 @@ ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel, while (ClassDecl && !Method) { if (ObjCImplementationDecl *ImpDecl = LookupObjCImplementation(ClassDecl->getIdentifier())) - Method = ImpDecl->getClassMethod(Context, Sel); + Method = ImpDecl->getClassMethod(Sel); // Look through local category implementations associated with the class. if (!Method) { for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) { if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl) - Method = ObjCCategoryImpls[i]->getClassMethod(Context, Sel); + Method = ObjCCategoryImpls[i]->getClassMethod(Sel); } } @@ -257,7 +257,7 @@ ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel, // But only in the root. This matches gcc's behaviour and what the // runtime expects. if (!Method && !ClassDecl->getSuperClass()) { - Method = ClassDecl->lookupInstanceMethod(Context, Sel); + Method = ClassDecl->lookupInstanceMethod(Sel); // Look through local category implementations associated // with the root class. if (!Method) @@ -276,13 +276,13 @@ ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel, // If we have implementations in scope, check "private" methods. if (ObjCImplementationDecl *ImpDecl = LookupObjCImplementation(ClassDecl->getIdentifier())) - Method = ImpDecl->getInstanceMethod(Context, Sel); + Method = ImpDecl->getInstanceMethod(Sel); // Look through local category implementations associated with the class. if (!Method) { for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) { if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl) - Method = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel); + Method = ObjCCategoryImpls[i]->getInstanceMethod(Sel); } } ClassDecl = ClassDecl->getSuperClass(); @@ -301,7 +301,7 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr( // Search for a declared property first. Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName); - ObjCMethodDecl *Getter = IFace->lookupClassMethod(Context, Sel); + ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel); // If this reference is in an @implementation, check for 'private' methods. if (!Getter) @@ -309,7 +309,7 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr( if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) if (ObjCImplementationDecl *ImpDecl = LookupObjCImplementation(ClassDecl->getIdentifier())) - Getter = ImpDecl->getClassMethod(Context, Sel); + Getter = ImpDecl->getClassMethod(Sel); if (Getter) { // FIXME: refactor/share with ActOnMemberReference(). @@ -323,7 +323,7 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr( SelectorTable::constructSetterName(PP.getIdentifierTable(), PP.getSelectorTable(), &propertyName); - ObjCMethodDecl *Setter = IFace->lookupClassMethod(Context, SetterSel); + ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel); if (!Setter) { // If this reference is in an @implementation, also check for 'private' // methods. @@ -331,13 +331,13 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr( if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) if (ObjCImplementationDecl *ImpDecl = LookupObjCImplementation(ClassDecl->getIdentifier())) - Setter = ImpDecl->getClassMethod(Context, SetterSel); + Setter = ImpDecl->getClassMethod(SetterSel); } // Look through local category implementations associated with the class. if (!Setter) { for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) { if (ObjCCategoryImpls[i]->getClassInterface() == IFace) - Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel); + Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel); } } @@ -450,7 +450,7 @@ Sema::ExprResult Sema::ActOnClassMessage( << Method->getDeclName(); } if (!Method) - Method = ClassDecl->lookupClassMethod(Context, Sel); + Method = ClassDecl->lookupClassMethod(Sel); // If we have an implementation in scope, check "private" methods. if (!Method) @@ -507,7 +507,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, // If we have an interface in scope, check 'super' methods. if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass()) { - Method = SuperDecl->lookupInstanceMethod(Context, Sel); + Method = SuperDecl->lookupInstanceMethod(Sel); if (!Method) // If we have implementations in scope, check "private" methods. @@ -550,7 +550,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) { // First check the public methods in the class interface. - Method = ClassDecl->lookupClassMethod(Context, Sel); + Method = ClassDecl->lookupClassMethod(Sel); if (!Method) Method = LookupPrivateClassMethod(Sel, ClassDecl); @@ -596,10 +596,10 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(), E = QIdTy->qual_end(); I != E; ++I) { ObjCProtocolDecl *PDecl = *I; - if (PDecl && (Method = PDecl->lookupInstanceMethod(Context, Sel))) + if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel))) break; // Since we aren't supporting "Class", look for a class method. - if (PDecl && (Method = PDecl->lookupClassMethod(Context, Sel))) + if (PDecl && (Method = PDecl->lookupClassMethod(Sel))) break; } } else if (const ObjCInterfaceType *OCIType = @@ -610,13 +610,13 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be // faster than the following method (which can do *many* linear searches). // The idea is to add class info to InstanceMethodPool. - Method = ClassDecl->lookupInstanceMethod(Context, Sel); + Method = ClassDecl->lookupInstanceMethod(Sel); if (!Method) { // Search protocol qualifiers. for (ObjCQualifiedInterfaceType::qual_iterator QI = OCIType->qual_begin(), E = OCIType->qual_end(); QI != E; ++QI) { - if ((Method = (*QI)->lookupInstanceMethod(Context, Sel))) + if ((Method = (*QI)->lookupInstanceMethod(Sel))) break; } } diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp index 28ca5f64ef59..2f914f14a81f 100644 --- a/lib/Sema/SemaInherit.cpp +++ b/lib/Sema/SemaInherit.cpp @@ -187,7 +187,7 @@ bool Sema::LookupInBases(CXXRecordDecl *Class, = (Context.getCanonicalType(BaseSpec->getType()) == Criteria.Base); break; case MemberLookupCriteria::LK_NamedMember: - Paths.ScratchPath.Decls = BaseRecord->lookup(Context, Criteria.Name); + Paths.ScratchPath.Decls = BaseRecord->lookup(Criteria.Name); while (Paths.ScratchPath.Decls.first != Paths.ScratchPath.Decls.second) { if (isAcceptableLookupResult(*Paths.ScratchPath.Decls.first, Criteria.NameKind, Criteria.IDNS)) { @@ -199,7 +199,7 @@ bool Sema::LookupInBases(CXXRecordDecl *Class, break; case MemberLookupCriteria::LK_OverriddenMember: Paths.ScratchPath.Decls = - BaseRecord->lookup(Context, Criteria.Method->getDeclName()); + BaseRecord->lookup(Criteria.Method->getDeclName()); while (Paths.ScratchPath.Decls.first != Paths.ScratchPath.Decls.second) { if (CXXMethodDecl *MD = dyn_cast(*Paths.ScratchPath.Decls.first)) { diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 6b812e1968de..ecfdfd7ba0b6 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -343,8 +343,8 @@ void InitListChecker::FillInValueInitializations(InitListExpr *ILE) { if (const RecordType *RType = ILE->getType()->getAsRecordType()) { unsigned Init = 0, NumInits = ILE->getNumInits(); for (RecordDecl::field_iterator - Field = RType->getDecl()->field_begin(SemaRef.Context), - FieldEnd = RType->getDecl()->field_end(SemaRef.Context); + Field = RType->getDecl()->field_begin(), + FieldEnd = RType->getDecl()->field_end(); Field != FieldEnd; ++Field) { if (Field->isUnnamedBitfield()) continue; @@ -449,8 +449,8 @@ int InitListChecker::numStructUnionElements(QualType DeclType) { RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl(); int InitializableMembers = 0; for (RecordDecl::field_iterator - Field = structDecl->field_begin(SemaRef.Context), - FieldEnd = structDecl->field_end(SemaRef.Context); + Field = structDecl->field_begin(), + FieldEnd = structDecl->field_end(); Field != FieldEnd; ++Field) { if ((*Field)->getIdentifier() || !(*Field)->isBitField()) ++InitializableMembers; @@ -580,7 +580,7 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList, } else if (DeclType->isAggregateType()) { if (DeclType->isRecordType()) { RecordDecl *RD = DeclType->getAsRecordType()->getDecl(); - CheckStructUnionTypes(IList, DeclType, RD->field_begin(SemaRef.Context), + CheckStructUnionTypes(IList, DeclType, RD->field_begin(), SubobjectIsDesignatorContext, Index, StructuredList, StructuredIndex, TopLevelObject); @@ -946,7 +946,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList, if (DeclType->isUnionType() && IList->getNumInits() == 0) { // Value-initialize the first named member of the union. RecordDecl *RD = DeclType->getAsRecordType()->getDecl(); - for (RecordDecl::field_iterator FieldEnd = RD->field_end(SemaRef.Context); + for (RecordDecl::field_iterator FieldEnd = RD->field_end(); Field != FieldEnd; ++Field) { if (Field->getDeclName()) { StructuredList->setInitializedFieldInUnion(*Field); @@ -961,7 +961,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList, // because an error should get printed out elsewhere. It might be // worthwhile to skip over the rest of the initializer, though. RecordDecl *RD = DeclType->getAsRecordType()->getDecl(); - RecordDecl::field_iterator FieldEnd = RD->field_end(SemaRef.Context); + RecordDecl::field_iterator FieldEnd = RD->field_end(); bool InitializedSomething = false; while (Index < IList->getNumInits()) { Expr *Init = IList->getInit(Index); @@ -1090,9 +1090,9 @@ static void ExpandAnonymousFieldDesignator(Sema &SemaRef, // Update FieldIter/FieldIndex; RecordDecl *Record = cast(Path.back()->getDeclContext()); - FieldIter = Record->field_begin(SemaRef.Context); + FieldIter = Record->field_begin(); FieldIndex = 0; - for (RecordDecl::field_iterator FEnd = Record->field_end(SemaRef.Context); + for (RecordDecl::field_iterator FEnd = Record->field_end(); FieldIter != FEnd; ++FieldIter) { if (FieldIter->isUnnamedBitfield()) continue; @@ -1217,8 +1217,8 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList, IdentifierInfo *FieldName = D->getFieldName(); unsigned FieldIndex = 0; RecordDecl::field_iterator - Field = RT->getDecl()->field_begin(SemaRef.Context), - FieldEnd = RT->getDecl()->field_end(SemaRef.Context); + Field = RT->getDecl()->field_begin(), + FieldEnd = RT->getDecl()->field_end(); for (; Field != FieldEnd; ++Field) { if (Field->isUnnamedBitfield()) continue; @@ -1235,8 +1235,7 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList, // something that we can't designate (e.g., a member function), // may find nothing, or may find a member of an anonymous // struct/union. - DeclContext::lookup_result Lookup - = RT->getDecl()->lookup(SemaRef.Context, FieldName); + DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName); if (Lookup.first == Lookup.second) { // Name lookup didn't find anything. SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown) @@ -1565,8 +1564,8 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index, if (RDecl->isUnion()) NumElements = 1; else - NumElements = std::distance(RDecl->field_begin(SemaRef.Context), - RDecl->field_end(SemaRef.Context)); + NumElements = std::distance(RDecl->field_begin(), + RDecl->field_end()); } if (NumElements < NumInits) diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index cc9e783f6166..6f2fc5e0c434 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -65,7 +65,7 @@ void AddNamespaceUsingDirectives(ASTContext &Context, NamespaceSet &Visited) { DeclContext::udir_iterator I, End; - for (llvm::tie(I, End) = NS->getUsingDirectives(Context); I !=End; ++I) { + for (llvm::tie(I, End) = NS->getUsingDirectives(); I !=End; ++I) { UDirs.push_back(*I); std::push_heap(UDirs.begin(), UDirs.end(), UsingDirAncestorCompare()); NamespaceDecl *Nominated = (*I)->getNominatedNamespace(); @@ -609,7 +609,7 @@ CppNamespaceLookup(ASTContext &Context, DeclContext *NS, // Perform qualified name lookup into the LookupCtx. DeclContext::lookup_iterator I, E; - for (llvm::tie(I, E) = NS->lookup(Context, Name); I != E; ++I) + for (llvm::tie(I, E) = NS->lookup(Name); I != E; ++I) if (Sema::isAcceptableLookupResult(*I, NameKind, IDNS)) { Results.push_back(Sema::LookupResult::CreateLookupResult(Context, I, E)); break; @@ -903,7 +903,7 @@ Sema::LookupName(Scope *S, DeclarationName Name, LookupNameKind NameKind, continue; } - if ((*I)->getAttr(Context)) { + if ((*I)->getAttr()) { // If this declaration has the "overloadable" attribute, we // might have a set of overloaded functions. @@ -1005,7 +1005,7 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name, // Perform qualified name lookup into the LookupCtx. DeclContext::lookup_iterator I, E; - for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I) + for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I) if (isAcceptableLookupResult(*I, NameKind, IDNS)) return LookupResult::CreateLookupResult(Context, I, E); @@ -1148,7 +1148,7 @@ Sema::LookupParsedName(Scope *S, const CXXScopeSpec *SS, // (C++0x [temp.dep.type]). unsigned IDNS = getIdentifierNamespacesFromLookupNameKind(NameKind, true); DeclContext::lookup_iterator I, E; - for (llvm::tie(I, E) = Current->lookup(Context, Name); I != E; ++I) + for (llvm::tie(I, E) = Current->lookup(Name); I != E; ++I) if (isAcceptableLookupResult(*I, NameKind, IDNS)) return LookupResult::CreateLookupResult(Context, I, E); } @@ -1604,9 +1604,17 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end(); Op != OpEnd; ++Op) { - if (FunctionDecl *FD = dyn_cast(*Op)) + if (FunctionDecl *FD = dyn_cast(*Op)) { if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context)) Functions.insert(FD); // FIXME: canonical FD + } else if (FunctionTemplateDecl *FunTmpl + = dyn_cast(*Op)) { + // FIXME: friend operators? + // FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate, + // later? + if (!FunTmpl->getDeclContext()->isRecord()) + Functions.insert(FunTmpl); + } } } @@ -1648,25 +1656,23 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, // namespaces even if they are not visible during an ordinary // lookup (11.4). DeclContext::lookup_iterator I, E; - for (llvm::tie(I, E) = (*NS)->lookup(Context, Name); I != E; ++I) { - FunctionDecl *Func = dyn_cast(*I); - if (!Func) - break; - - Functions.insert(Func); + for (llvm::tie(I, E) = (*NS)->lookup(Name); I != E; ++I) { + if (FunctionDecl *Func = dyn_cast(*I)) + Functions.insert(Func); + else if (FunctionTemplateDecl *FunTmpl = dyn_cast(*I)) + Functions.insert(FunTmpl); } } if (GlobalScope) { DeclContext::lookup_iterator I, E; for (llvm::tie(I, E) - = Context.getTranslationUnitDecl()->lookup(Context, Name); + = Context.getTranslationUnitDecl()->lookup(Name); I != E; ++I) { - FunctionDecl *Func = dyn_cast(*I); - if (!Func) - break; - - Functions.insert(Func); + if (FunctionDecl *Func = dyn_cast(*I)) + Functions.insert(Func); + else if (FunctionTemplateDecl *FunTmpl = dyn_cast(*I)) + Functions.insert(FunTmpl); } } } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index fcc155750cdc..03ac2d9bb73a 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1375,7 +1375,7 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, Context.getCanonicalType(ToType).getUnqualifiedType()); DeclContext::lookup_iterator Con, ConEnd; for (llvm::tie(Con, ConEnd) - = ToRecordDecl->lookup(Context, ConstructorName); + = ToRecordDecl->lookup(ConstructorName); Con != ConEnd; ++Con) { CXXConstructorDecl *Constructor = cast(*Con); if (Constructor->isConvertingConstructor()) @@ -2161,9 +2161,16 @@ void Sema::AddFunctionCandidates(const FunctionSet &Functions, bool SuppressUserConversions) { for (FunctionSet::const_iterator F = Functions.begin(), FEnd = Functions.end(); - F != FEnd; ++F) - AddOverloadCandidate(*F, Args, NumArgs, CandidateSet, - SuppressUserConversions); + F != FEnd; ++F) { + if (FunctionDecl *FD = dyn_cast(*F)) + AddOverloadCandidate(FD, Args, NumArgs, CandidateSet, + SuppressUserConversions); + else + AddTemplateOverloadCandidate(cast(*F), + /*FIXME: explicit args */false, 0, 0, + Args, NumArgs, CandidateSet, + SuppressUserConversions); + } } /// AddMethodCandidate - Adds the given C++ member function to the set @@ -2267,6 +2274,9 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object, /// template specialization. void Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, + bool HasExplicitTemplateArgs, + const TemplateArgument *ExplicitTemplateArgs, + unsigned NumExplicitTemplateArgs, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions, @@ -2283,8 +2293,9 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, TemplateDeductionInfo Info(Context); FunctionDecl *Specialization = 0; if (TemplateDeductionResult Result - = DeduceTemplateArguments(FunctionTemplate, Args, NumArgs, - Specialization, Info)) { + = DeduceTemplateArguments(FunctionTemplate, HasExplicitTemplateArgs, + ExplicitTemplateArgs, NumExplicitTemplateArgs, + Args, NumArgs, Specialization, Info)) { // FIXME: Record what happened with template argument deduction, so // that we can give the user a beautiful diagnostic. (void)Result; @@ -2510,7 +2521,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, // FIXME: Lookup in base classes, too! if (const RecordType *T1Rec = T1->getAsRecordType()) { DeclContext::lookup_const_iterator Oper, OperEnd; - for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(Context, OpName); + for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(OpName); Oper != OperEnd; ++Oper) AddMethodCandidate(cast(*Oper), Args[0], Args+1, NumArgs - 1, CandidateSet, @@ -3405,8 +3416,11 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(), CandEnd = CandidateSet.end(); Cand != CandEnd; ++Cand) - if (Cand->Function) + if (Cand->Function) { Functions.insert(Cand->Function); + if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate()) + Functions.insert(FunTmpl); + } ArgumentDependentLookup(Name, Args, NumArgs, Functions); @@ -3415,15 +3429,24 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(), CandEnd = CandidateSet.end(); Cand != CandEnd; ++Cand) - if (Cand->Function) + if (Cand->Function) { Functions.erase(Cand->Function); + if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate()) + Functions.erase(FunTmpl); + } // For each of the ADL candidates we found, add it to the overload // set. for (FunctionSet::iterator Func = Functions.begin(), FuncEnd = Functions.end(); - Func != FuncEnd; ++Func) - AddOverloadCandidate(*Func, Args, NumArgs, CandidateSet); + Func != FuncEnd; ++Func) { + if (FunctionDecl *FD = dyn_cast(*Func)) + AddOverloadCandidate(FD, Args, NumArgs, CandidateSet); + else + AddTemplateOverloadCandidate(cast(*Func), + /*FIXME: explicit args */false, 0, 0, + Args, NumArgs, CandidateSet); + } } /// isBetterOverloadCandidate - Determines whether the first overload @@ -3556,7 +3579,7 @@ Sema::BestViableFunction(OverloadCandidateSet& CandidateSet, // Best is the best viable function. if (Best->Function && (Best->Function->isDeleted() || - Best->Function->getAttr(Context))) + Best->Function->getAttr())) return OR_Deleted; // C++ [basic.def.odr]p2: @@ -3583,7 +3606,7 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet, if (Cand->Viable || !OnlyViable) { if (Cand->Function) { if (Cand->Function->isDeleted() || - Cand->Function->getAttr(Context)) { + Cand->Function->getAttr()) { // Deleted or "unavailable" function. Diag(Cand->Function->getLocation(), diag::err_ovl_candidate_deleted) << Cand->Function->isDeleted(); @@ -3741,6 +3764,9 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, /// arguments and Fn, and returns NULL. FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, DeclarationName UnqualifiedName, + bool HasExplicitTemplateArgs, + const TemplateArgument *ExplicitTemplateArgs, + unsigned NumExplicitTemplateArgs, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, SourceLocation *CommaLocs, @@ -3773,11 +3799,17 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, Func != FuncEnd; ++Func) { DeclContext *Ctx = 0; if (FunctionDecl *FunDecl = dyn_cast(*Func)) { + if (HasExplicitTemplateArgs) + continue; + AddOverloadCandidate(FunDecl, Args, NumArgs, CandidateSet); Ctx = FunDecl->getDeclContext(); } else { FunctionTemplateDecl *FunTmpl = cast(*Func); - AddTemplateOverloadCandidate(FunTmpl, Args, NumArgs, CandidateSet); + AddTemplateOverloadCandidate(FunTmpl, HasExplicitTemplateArgs, + ExplicitTemplateArgs, + NumExplicitTemplateArgs, + Args, NumArgs, CandidateSet); Ctx = FunTmpl->getDeclContext(); } @@ -3786,6 +3818,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, ArgumentDependentLookup = false; } } else if (FunctionDecl *Func = dyn_cast_or_null(Callee)) { + assert(!HasExplicitTemplateArgs && "Explicit template arguments?"); AddOverloadCandidate(Func, Args, NumArgs, CandidateSet); if (Func->getDeclContext()->isRecord() || @@ -3793,7 +3826,10 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, ArgumentDependentLookup = false; } else if (FunctionTemplateDecl *FuncTemplate = dyn_cast_or_null(Callee)) { - AddTemplateOverloadCandidate(FuncTemplate, Args, NumArgs, CandidateSet); + AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs, + ExplicitTemplateArgs, + NumExplicitTemplateArgs, + Args, NumArgs, CandidateSet); if (FuncTemplate->getDeclContext()->isRecord()) ArgumentDependentLookup = false; @@ -3802,6 +3838,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, if (Callee) UnqualifiedName = Callee->getDeclName(); + // FIXME: Pass explicit template arguments through for ADL if (ArgumentDependentLookup) AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs, CandidateSet); @@ -4273,7 +4310,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, OverloadCandidateSet CandidateSet; DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call); DeclContext::lookup_const_iterator Oper, OperEnd; - for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(Context, OpName); + for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(OpName); Oper != OperEnd; ++Oper) AddMethodCandidate(cast(*Oper), Object, Args, NumArgs, CandidateSet, /*SuppressUserConversions=*/false); @@ -4477,8 +4514,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, DeclContext::lookup_const_iterator Oper, OperEnd; for (llvm::tie(Oper, OperEnd) - = BaseRecord->getDecl()->lookup(Context, OpName); - Oper != OperEnd; ++Oper) + = BaseRecord->getDecl()->lookup(OpName); Oper != OperEnd; ++Oper) AddMethodCandidate(cast(*Oper), Base, 0, 0, CandidateSet, /*SuppressUserConversions=*/false); diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 914839cbf790..63191e0e00cc 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -84,7 +84,7 @@ Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, SourceLocation Loc; SourceRange R1, R2; - if (!E->isUnusedResultAWarning(Loc, R1, R2, Context)) + if (!E->isUnusedResultAWarning(Loc, R1, R2)) continue; Diag(Loc, diag::warn_unused_expr) << R1 << R2; @@ -766,7 +766,7 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } QualType FnRetType = CurBlock->ReturnType; - if (CurBlock->TheDecl->hasAttr(Context)) { + if (CurBlock->TheDecl->hasAttr()) { Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr) << getCurFunctionOrMethodDecl()->getDeclName(); return StmtError(); @@ -842,7 +842,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, FullExprArg rex) { QualType FnRetType; if (const FunctionDecl *FD = getCurFunctionDecl()) { FnRetType = FD->getResultType(); - if (FD->hasAttr(Context)) + if (FD->hasAttr()) Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr) << getCurFunctionOrMethodDecl()->getDeclName(); } else if (ObjCMethodDecl *MD = getCurMethodDecl()) diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index cd985c536c77..568d68c9a7e8 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -852,7 +852,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, NumTemplateArgs); if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc, TemplateArgs, NumTemplateArgs, RAngleLoc, - Converted)) + false, Converted)) return QualType(); assert((Converted.structuredSize() == @@ -933,6 +933,42 @@ Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc, return Result.getAsOpaquePtr(); } +Sema::OwningExprResult Sema::BuildTemplateIdExpr(TemplateName Template, + SourceLocation TemplateNameLoc, + SourceLocation LAngleLoc, + const TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs, + SourceLocation RAngleLoc) { + // FIXME: Can we do any checking at this point? I guess we could check the + // template arguments that we have against the template name, if the template + // name refers to a single template. That's not a terribly common case, + // though. + return Owned(TemplateIdRefExpr::Create(Context, + /*FIXME: New type?*/Context.OverloadTy, + /*FIXME: Necessary?*/0, + /*FIXME: Necessary?*/SourceRange(), + Template, TemplateNameLoc, LAngleLoc, + TemplateArgs, + NumTemplateArgs, RAngleLoc)); +} + +Sema::OwningExprResult Sema::ActOnTemplateIdExpr(TemplateTy TemplateD, + SourceLocation TemplateNameLoc, + SourceLocation LAngleLoc, + ASTTemplateArgsPtr TemplateArgsIn, + SourceLocation *TemplateArgLocs, + SourceLocation RAngleLoc) { + TemplateName Template = TemplateD.getAsVal(); + + // Translate the parser's template argument list in our AST format. + llvm::SmallVector TemplateArgs; + translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs); + + return BuildTemplateIdExpr(Template, TemplateNameLoc, LAngleLoc, + TemplateArgs.data(), TemplateArgs.size(), + RAngleLoc); +} + /// \brief Form a dependent template name. /// /// This action forms a dependent template name given the template @@ -1019,6 +1055,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs, SourceLocation RAngleLoc, + bool PartialTemplateArgs, TemplateArgumentListBuilder &Converted) { TemplateParameterList *Params = Template->getTemplateParameters(); unsigned NumParams = Params->size(); @@ -1029,7 +1066,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack(); if ((NumArgs > NumParams && !HasParameterPack) || - NumArgs < Params->getMinRequiredArguments()) { + (NumArgs < Params->getMinRequiredArguments() && + !PartialTemplateArgs)) { // FIXME: point at either the first arg beyond what we can handle, // or the '>', depending on whether we have too many or too few // arguments. @@ -1056,6 +1094,9 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, for (TemplateParameterList::iterator Param = Params->begin(), ParamEnd = Params->end(); Param != ParamEnd; ++Param, ++ArgIdx) { + if (ArgIdx > NumArgs && PartialTemplateArgs) + break; + // Decode the template argument TemplateArgument Arg; if (ArgIdx >= NumArgs) { @@ -2302,7 +2343,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, TemplateArgs.size()); if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc, TemplateArgs.data(), TemplateArgs.size(), - RAngleLoc, Converted)) + RAngleLoc, false, Converted)) return true; assert((Converted.structuredSize() == @@ -2498,7 +2539,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, // Add the specialization into its lexical context, so that it can // be seen when iterating through the list of declarations in that // context. However, specializations are not found by name lookup. - CurContext->addDecl(Context, Specialization); + CurContext->addDecl(Specialization); return DeclPtrTy::make(Specialization); } @@ -2597,7 +2638,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, TemplateArgs.size()); if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc, TemplateArgs.data(), TemplateArgs.size(), - RAngleLoc, Converted)) + RAngleLoc, false, Converted)) return true; assert((Converted.structuredSize() == @@ -2654,7 +2695,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, ClassTemplate, Converted, 0); Specialization->setLexicalDeclContext(CurContext); - CurContext->addDecl(Context, Specialization); + CurContext->addDecl(Specialization); return DeclPtrTy::make(Specialization); } @@ -2703,7 +2744,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, // since explicit instantiations are never found by name lookup, we // just put it into the declaration context directly. Specialization->setLexicalDeclContext(CurContext); - CurContext->addDecl(Context, Specialization); + CurContext->addDecl(Specialization); // C++ [temp.explicit]p3: // A definition of a class template or class member template diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 3d909bb26a79..5a0578f6bcb7 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -868,6 +868,16 @@ static bool isSimpleTemplateIdType(QualType T) { /// \param FunctionTemplate the function template for which we are performing /// template argument deduction. /// +/// \param HasExplicitTemplateArgs whether any template arguments were +/// explicitly specified. +/// +/// \param ExplicitTemplateArguments when @p HasExplicitTemplateArgs is true, +/// the explicitly-specified template arguments. +/// +/// \param NumExplicitTemplateArguments when @p HasExplicitTemplateArgs is true, +/// the number of explicitly-specified template arguments in +/// @p ExplicitTemplateArguments. This value may be zero. +/// /// \param Args the function call arguments /// /// \param NumArgs the number of arguments in Args @@ -880,22 +890,22 @@ static bool isSimpleTemplateIdType(QualType T) { /// about template argument deduction. /// /// \returns the result of template argument deduction. -/// -/// FIXME: We will also need to pass in any explicitly-specified template -/// arguments. Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, + bool HasExplicitTemplateArgs, + const TemplateArgument *ExplicitTemplateArgs, + unsigned NumExplicitTemplateArgs, Expr **Args, unsigned NumArgs, FunctionDecl *&Specialization, TemplateDeductionInfo &Info) { FunctionDecl *Function = FunctionTemplate->getTemplatedDecl(); - + // C++ [temp.deduct.call]p1: // Template argument deduction is done by comparing each function template // parameter type (call it P) with the type of the corresponding argument // of the call (call it A) as described below. unsigned CheckArgs = NumArgs; - if (NumArgs < Function->getNumParams()) + if (NumArgs < Function->getMinRequiredArguments()) return TDK_TooFewArguments; else if (NumArgs > Function->getNumParams()) { const FunctionProtoType *Proto @@ -905,18 +915,87 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, CheckArgs = Function->getNumParams(); } - + // Template argument deduction for function templates in a SFINAE context. // Trap any errors that might occur. SFINAETrap Trap(*this); - - // Deduce template arguments from the function parameters. - llvm::SmallVector Deduced; - Deduced.resize(FunctionTemplate->getTemplateParameters()->size()); + + // The types of the parameters from which we will perform template argument + // deduction. TemplateParameterList *TemplateParams = FunctionTemplate->getTemplateParameters(); + llvm::SmallVector Deduced; + llvm::SmallVector ParamTypes; + if (NumExplicitTemplateArgs) { + // C++ [temp.arg.explicit]p3: + // Template arguments that are present shall be specified in the + // declaration order of their corresponding template-parameters. The + // template argument list shall not specify more template-arguments than + // there are corresponding template-parameters. + TemplateArgumentListBuilder Builder(TemplateParams, + NumExplicitTemplateArgs); + + // Enter a new template instantiation context where we check the + // explicitly-specified template arguments against this function template, + // and then substitute them into the function parameter types. + InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(), + FunctionTemplate, Deduced.data(), Deduced.size(), + ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution); + if (Inst) + return TDK_InstantiationDepth; + + if (CheckTemplateArgumentList(FunctionTemplate, + SourceLocation(), SourceLocation(), + ExplicitTemplateArgs, + NumExplicitTemplateArgs, + SourceLocation(), + true, + Builder) || Trap.hasErrorOccurred()) + return TDK_InvalidExplicitArguments; + + // Form the template argument list from the explicitly-specified + // template arguments. + TemplateArgumentList *ExplicitArgumentList + = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true); + Info.reset(ExplicitArgumentList); + + // Instantiate the types of each of the function parameters given the + // explicitly-specified template arguments. + for (FunctionDecl::param_iterator P = Function->param_begin(), + PEnd = Function->param_end(); + P != PEnd; + ++P) { + QualType ParamType = InstantiateType((*P)->getType(), + *ExplicitArgumentList, + (*P)->getLocation(), + (*P)->getDeclName()); + if (ParamType.isNull() || Trap.hasErrorOccurred()) + return TDK_SubstitutionFailure; + + ParamTypes.push_back(ParamType); + } + + // C++ [temp.arg.explicit]p2: + // Trailing template arguments that can be deduced (14.8.2) may be + // omitted from the list of explicit template- arguments. If all of the + // template arguments can be deduced, they may all be omitted; in this + // case, the empty template argument list <> itself may also be omitted. + // + // Take all of the explicitly-specified arguments and put them into the + // set of deduced template arguments. + Deduced.reserve(TemplateParams->size()); + for (unsigned I = 0, N = ExplicitArgumentList->size(); I != N; ++I) + Deduced.push_back(ExplicitArgumentList->get(I)); + } else { + // Just fill in the parameter types from the function declaration. + for (unsigned I = 0; I != CheckArgs; ++I) + ParamTypes.push_back(Function->getParamDecl(I)->getType()); + } + + // Deduce template arguments from the function parameters. + Deduced.resize(TemplateParams->size()); for (unsigned I = 0; I != CheckArgs; ++I) { - QualType ParamType = Function->getParamDecl(I)->getType(); + QualType ParamType = ParamTypes[I]; QualType ArgType = Args[I]->getType(); // C++ [temp.deduct.call]p2: @@ -998,11 +1077,6 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, // FIXME: C++ [temp.deduct.call] paragraphs 6-9 deal with function // pointer parameters. } - - InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(), - FunctionTemplate, Deduced.data(), Deduced.size()); - if (Inst) - return TDK_InstantiationDepth; // C++ [temp.deduct.type]p2: // [...] or if any template argument remains neither deduced nor @@ -1030,20 +1104,36 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true); Info.reset(DeducedArgumentList); + // Enter a new template instantiation context while we instantiate the + // actual function declaration. + InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(), + FunctionTemplate, Deduced.data(), Deduced.size(), + ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution); + if (Inst) + return TDK_InstantiationDepth; + // Substitute the deduced template arguments into the function template // declaration to produce the function template specialization. Specialization = cast_or_null( InstantiateDecl(FunctionTemplate->getTemplatedDecl(), FunctionTemplate->getDeclContext(), *DeducedArgumentList)); + if (!Specialization) + return TDK_SubstitutionFailure; - if (!Specialization || Trap.hasErrorOccurred()) + // If the template argument list is owned by the function template + // specialization, release it. + if (Specialization->getTemplateSpecializationArgs() == DeducedArgumentList) + Info.take(); + + // There may have been an error that did not prevent us from constructing a + // declaration. Mark the declaration invalid and return with a substitution + // failure. + if (Trap.hasErrorOccurred()) { + Specialization->setInvalidDecl(true); return TDK_SubstitutionFailure; - - // Turn the specialization into an actual function template specialization. - Specialization->setFunctionTemplateSpecialization(Context, - FunctionTemplate, - Info.take()); + } + return TDK_Success; } diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index aed348966a4f..6c2dc77b4cce 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -98,6 +98,30 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, } } +Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, + SourceLocation PointOfInstantiation, + FunctionTemplateDecl *FunctionTemplate, + const TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs, + ActiveTemplateInstantiation::InstantiationKind Kind, + SourceRange InstantiationRange) +: SemaRef(SemaRef) { + + Invalid = CheckInstantiationDepth(PointOfInstantiation, + InstantiationRange); + if (!Invalid) { + ActiveTemplateInstantiation Inst; + Inst.Kind = Kind; + Inst.PointOfInstantiation = PointOfInstantiation; + Inst.Entity = reinterpret_cast(FunctionTemplate); + Inst.TemplateArgs = TemplateArgs; + Inst.NumTemplateArgs = NumTemplateArgs; + Inst.InstantiationRange = InstantiationRange; + SemaRef.ActiveTemplateInstantiations.push_back(Inst); + Invalid = false; + } +} + Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, ClassTemplatePartialSpecializationDecl *PartialSpec, @@ -111,7 +135,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, if (!Invalid) { ActiveTemplateInstantiation Inst; Inst.Kind - = ActiveTemplateInstantiation::PartialSpecDeductionInstantiation; + = ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution; Inst.PointOfInstantiation = PointOfInstantiation; Inst.Entity = reinterpret_cast(PartialSpec); Inst.TemplateArgs = TemplateArgs; @@ -148,6 +172,7 @@ bool Sema::InstantiatingTemplate::CheckInstantiationDepth( /// \brief Prints the current instantiation stack through a series of /// notes. void Sema::PrintInstantiationStack() { + // FIXME: In all of these cases, we need to show the template arguments for (llvm::SmallVector::reverse_iterator Active = ActiveTemplateInstantiations.rbegin(), ActiveEnd = ActiveTemplateInstantiations.rend(); @@ -183,7 +208,7 @@ void Sema::PrintInstantiationStack() { TemplateDecl *Template = cast((Decl *)Active->Entity); std::string TemplateArgsStr = TemplateSpecializationType::PrintTemplateArgumentList( - Active->TemplateArgs, + Active->TemplateArgs, Active->NumTemplateArgs, Context.PrintingPolicy); Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr), @@ -193,18 +218,31 @@ void Sema::PrintInstantiationStack() { break; } - case ActiveTemplateInstantiation::PartialSpecDeductionInstantiation: { - ClassTemplatePartialSpecializationDecl *PartialSpec - = cast((Decl *)Active->Entity); - // FIXME: The active template instantiation's template arguments - // are interesting, too. We should add something like [with T = - // foo, U = bar, etc.] to the string. + case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution: { + FunctionTemplateDecl *FnTmpl + = cast((Decl *)Active->Entity); Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr), - diag::note_partial_spec_deduct_instantiation_here) - << Context.getTypeDeclType(PartialSpec) - << Active->InstantiationRange; + diag::note_explicit_template_arg_substitution_here) + << FnTmpl << Active->InstantiationRange; break; } + + case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution: + if (ClassTemplatePartialSpecializationDecl *PartialSpec + = dyn_cast( + (Decl *)Active->Entity)) { + Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr), + diag::note_partial_spec_deduct_instantiation_here) + << Context.getTypeDeclType(PartialSpec) + << Active->InstantiationRange; + } else { + FunctionTemplateDecl *FnTmpl + = cast((Decl *)Active->Entity); + Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr), + diag::note_function_template_deduction_instantiation_here) + << FnTmpl << Active->InstantiationRange; + } + break; } } @@ -219,19 +257,20 @@ bool Sema::isSFINAEContext() const { ++Active) { switch(Active->Kind) { - case ActiveTemplateInstantiation::PartialSpecDeductionInstantiation: - // We're in a template argument deduction context, so SFINAE - // applies. - return true; - + case ActiveTemplateInstantiation::TemplateInstantiation: + // This is a template instantiation, so there is no SFINAE. + return false; + case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation: // A default template argument instantiation may or may not be a // SFINAE context; look further up the stack. break; - - case ActiveTemplateInstantiation::TemplateInstantiation: - // This is a template instantiation, so there is no SFINAE. - return false; + + case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution: + case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution: + // We're either substitution explicitly-specified template arguments + // or deduced template arguments, so SFINAE applies. + return true; } } @@ -530,7 +569,7 @@ TemplateTypeInstantiator::InstantiateTypeOfExprType( if (E.isInvalid()) return QualType(); - return SemaRef.Context.getTypeOfExprType(E.takeAs()); + return SemaRef.BuildTypeofExprType(E.takeAs()); } QualType @@ -555,7 +594,7 @@ TemplateTypeInstantiator::InstantiateDecltypeType(const DecltypeType *T) const { if (E.isInvalid()) return QualType(); - return SemaRef.Context.getDecltypeType(E.takeAs()); + return SemaRef.BuildDecltypeType(E.takeAs()); } QualType @@ -584,6 +623,15 @@ InstantiateTemplateTypeParmType(const TemplateTypeParmType *T) const { if (T->getDepth() == 0) { // Replace the template type parameter with its corresponding // template argument. + + // If the corresponding template argument is NULL or doesn't exist, it's + // because we are performing instantiation from explicitly-specified + // template arguments in a function template class, but there were some + // arguments left unspecified. + if (T->getIndex() >= TemplateArgs.size() || + TemplateArgs[T->getIndex()].isNull()) + return QualType(T, 0); // Would be nice to keep the original type here + assert(TemplateArgs[T->getIndex()].getKind() == TemplateArgument::Type && "Template argument kind mismatch"); return TemplateArgs[T->getIndex()].getAsType(); @@ -859,8 +907,8 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, Invalid = true; llvm::SmallVector Fields; - for (RecordDecl::decl_iterator Member = Pattern->decls_begin(Context), - MemberEnd = Pattern->decls_end(Context); + for (RecordDecl::decl_iterator Member = Pattern->decls_begin(), + MemberEnd = Pattern->decls_end(); Member != MemberEnd; ++Member) { Decl *NewMember = InstantiateDecl(*Member, Instantiation, TemplateArgs); if (NewMember) { @@ -996,11 +1044,11 @@ void Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, CXXRecordDecl *Instantiation, const TemplateArgumentList &TemplateArgs) { - for (DeclContext::decl_iterator D = Instantiation->decls_begin(Context), - DEnd = Instantiation->decls_end(Context); + for (DeclContext::decl_iterator D = Instantiation->decls_begin(), + DEnd = Instantiation->decls_end(); D != DEnd; ++D) { if (FunctionDecl *Function = dyn_cast(*D)) { - if (!Function->getBody(Context)) + if (!Function->getBody()) InstantiateFunctionDefinition(PointOfInstantiation, Function); } else if (VarDecl *Var = dyn_cast(*D)) { const VarDecl *Def = 0; diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index a05095fa57a6..f59719992066 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -98,7 +98,7 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) { if (Invalid) Typedef->setInvalidDecl(); - Owner->addDecl(SemaRef.Context, Typedef); + Owner->addDecl(Typedef); return Typedef; } @@ -124,7 +124,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { // are not static data members. bool Redeclaration = false; SemaRef.CheckVariableDeclaration(Var, 0, Redeclaration); - Owner->addDecl(SemaRef.Context, Var); + Owner->addDecl(Var); if (D->getInit()) { OwningExprResult Init @@ -188,7 +188,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { if (Invalid) Field->setInvalidDecl(); - Owner->addDecl(SemaRef.Context, Field); + Owner->addDecl(Field); } return Field; @@ -219,14 +219,14 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { /*PrevDecl=*/0); Enum->setInstantiationOfMemberEnum(D); Enum->setAccess(D->getAccess()); - Owner->addDecl(SemaRef.Context, Enum); + Owner->addDecl(Enum); Enum->startDefinition(); llvm::SmallVector Enumerators; EnumConstantDecl *LastEnumConst = 0; - for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(SemaRef.Context), - ECEnd = D->enumerator_end(SemaRef.Context); + for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(), + ECEnd = D->enumerator_end(); EC != ECEnd; ++EC) { // The specified value for the enumerator. OwningExprResult Value = SemaRef.Owned((Expr *)0); @@ -257,7 +257,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { } if (EnumConst) { - Enum->addDecl(SemaRef.Context, EnumConst); + Enum->addDecl(EnumConst); Enumerators.push_back(Sema::DeclPtrTy::make(EnumConst)); LastEnumConst = EnumConst; } @@ -289,12 +289,29 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { if (!D->isInjectedClassName()) Record->setInstantiationOfMemberClass(D); - Owner->addDecl(SemaRef.Context, Record); + Owner->addDecl(Record); return Record; } Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) { - // FIXME: Look for existing specializations (explicit or otherwise). + // Check whether there is already a function template specialization for + // this declaration. + FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate(); + void *InsertPos = 0; + if (FunctionTemplate) { + llvm::FoldingSetNodeID ID; + FunctionTemplateSpecializationInfo::Profile(ID, + TemplateArgs.getFlatArgumentList(), + TemplateArgs.flat_size()); + + FunctionTemplateSpecializationInfo *Info + = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID, + InsertPos); + + // If we already have a function template specialization, return it. + if (Info) + return Info->Function; + } Sema::LocalInstantiationScope Scope(SemaRef); @@ -325,10 +342,15 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) { NamedDecl *PrevDecl = 0; SemaRef.CheckFunctionDeclaration(Function, PrevDecl, Redeclaration, /*FIXME:*/OverloadableAttrRequired); - - // FIXME: link this to the function template from which it was instantiated. - + if (FunctionTemplate) { + // Record this function template specialization. + Function->setFunctionTemplateSpecialization(SemaRef.Context, + FunctionTemplate, + &TemplateArgs, + InsertPos); + } + return Function; } @@ -372,7 +394,7 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { /*FIXME:*/OverloadableAttrRequired); if (!Method->isInvalidDecl() || !PrevDecl) - Owner->addDecl(SemaRef.Context, Method); + Owner->addDecl(Method); return Method; } @@ -420,7 +442,7 @@ Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) { /*FIXME:*/OverloadableAttrRequired); Record->addedConstructor(SemaRef.Context, Constructor); - Owner->addDecl(SemaRef.Context, Constructor); + Owner->addDecl(Constructor); return Constructor; } @@ -452,7 +474,7 @@ Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) { NamedDecl *PrevDecl = 0; SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration, /*FIXME:*/OverloadableAttrRequired); - Owner->addDecl(SemaRef.Context, Destructor); + Owner->addDecl(Destructor); return Destructor; } @@ -485,7 +507,7 @@ Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) { NamedDecl *PrevDecl = 0; SemaRef.CheckFunctionDeclaration(Conversion, PrevDecl, Redeclaration, /*FIXME:*/OverloadableAttrRequired); - Owner->addDecl(SemaRef.Context, Conversion); + Owner->addDecl(Conversion); return Conversion; } @@ -606,6 +628,28 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl) { if (Tmpl->isDeleted()) New->setDeleted(); + + // If we are performing substituting explicitly-specified template arguments + // or deduced template arguments into a function template and we reach this + // point, we are now past the point where SFINAE applies and have committed + // to keeping the new function template specialization. We therefore + // convert the active template instantiation for the function template + // into a template instantiation for this specific function template + // specialization, which is not a SFINAE context, so that we diagnose any + // further errors in the declaration itself. + typedef Sema::ActiveTemplateInstantiation ActiveInstType; + ActiveInstType &ActiveInst = SemaRef.ActiveTemplateInstantiations.back(); + if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution || + ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) { + if (FunctionTemplateDecl *FunTmpl + = dyn_cast((Decl *)ActiveInst.Entity)) { + assert(FunTmpl->getTemplatedDecl() == Tmpl && + "Deduction from the wrong function template?"); + ActiveInst.Kind = ActiveInstType::TemplateInstantiation; + ActiveInst.Entity = reinterpret_cast(New); + } + } + return false; } @@ -641,14 +685,23 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New, /// \brief Instantiate the definition of the given function from its /// template. /// +/// \param PointOfInstantiation the point at which the instantiation was +/// required. Note that this is not precisely a "point of instantiation" +/// for the function, but it's close. +/// /// \param Function the already-instantiated declaration of a -/// function. +/// function template specialization or member function of a class template +/// specialization. +/// +/// \param Recursive if true, recursively instantiates any functions that +/// are required by this instantiation. void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, - FunctionDecl *Function) { + FunctionDecl *Function, + bool Recursive) { if (Function->isInvalidDecl()) return; - assert(!Function->getBody(Context) && "Already instantiated!"); + assert(!Function->getBody() && "Already instantiated!"); // Find the function body that we'll be substituting. const FunctionDecl *PatternDecl = 0; @@ -658,7 +711,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, PatternDecl = Function->getInstantiatedFromMemberFunction(); Stmt *Pattern = 0; if (PatternDecl) - Pattern = PatternDecl->getBody(Context, PatternDecl); + Pattern = PatternDecl->getBody(PatternDecl); if (!Pattern) return; @@ -667,6 +720,13 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (Inst) return; + // If we're performing recursive template instantiation, create our own + // queue of pending implicit instantiations that we will instantiate later, + // while we're still within our own instantiation context. + std::deque SavedPendingImplicitInstantiations; + if (Recursive) + PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations); + ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function)); // Introduce a new scope where local variable instantiations will be @@ -695,6 +755,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, DeclGroupRef DG(Function); Consumer.HandleTopLevelDecl(DG); + + if (Recursive) { + // Instantiate any pending implicit instantiations found during the + // instantiation of this template. + PerformPendingImplicitInstantiations(); + + // Restore the set of pending implicit instantiations. + PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations); + } } /// \brief Instantiate the definition of the given variable from its @@ -787,8 +856,7 @@ NamedDecl * Sema::InstantiateCurrentDeclRef(NamedDecl *D) { // find the instantiation of the declaration D. NamedDecl *Result = 0; if (D->getDeclName()) { - DeclContext::lookup_result Found - = ParentDC->lookup(Context, D->getDeclName()); + DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName()); Result = findInstantiationOf(Context, D, Found.first, Found.second); } else { // Since we don't have a name for the entity we're looking for, @@ -800,8 +868,8 @@ NamedDecl * Sema::InstantiateCurrentDeclRef(NamedDecl *D) { // // FIXME: Find a better way to find these instantiations! Result = findInstantiationOf(Context, D, - ParentDC->decls_begin(Context), - ParentDC->decls_end(Context)); + ParentDC->decls_begin(), + ParentDC->decls_end()); } assert(Result && "Unable to find instantiation of declaration!"); D = Result; @@ -838,12 +906,12 @@ NamedDecl * Sema::InstantiateCurrentDeclRef(NamedDecl *D) { void Sema::PerformPendingImplicitInstantiations() { while (!PendingImplicitInstantiations.empty()) { PendingImplicitInstantiation Inst = PendingImplicitInstantiations.front(); - PendingImplicitInstantiations.pop(); + PendingImplicitInstantiations.pop_front(); if (FunctionDecl *Function = dyn_cast(Inst.first)) - if (!Function->getBody(Context)) - InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function); + if (!Function->getBody()) + InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true); - // FIXME: instantiation static member variables + // FIXME: instantiate static member variables } } diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp index 65a35f92f7c6..c82e1a7da3c9 100644 --- a/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -106,13 +106,50 @@ TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr( return SemaRef.Clone(E); } +Sema::OwningExprResult +TemplateExprInstantiator::VisitTemplateIdRefExpr(TemplateIdRefExpr *E) { + TemplateName Template + = SemaRef.InstantiateTemplateName(E->getTemplateName(), E->getTemplateNameLoc(), + TemplateArgs); + // FIXME: Can InstantiateTemplateName report an error? + + llvm::SmallVector InstantiatedArgs; + for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) { + TemplateArgument InstArg = SemaRef.Instantiate(E->getTemplateArgs()[I], + TemplateArgs); + if (InstArg.isNull()) + return SemaRef.ExprError(); + + InstantiatedArgs.push_back(InstArg); + } + + // FIXME: It's possible that we'll find out now that the template name + // actually refers to a type, in which case this is a functional cast. + // Implement this! + + return SemaRef.BuildTemplateIdExpr(Template, E->getTemplateNameLoc(), + E->getLAngleLoc(), + InstantiatedArgs.data(), + InstantiatedArgs.size(), + E->getRAngleLoc()); +} + Sema::OwningExprResult TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) { NamedDecl *D = E->getDecl(); if (NonTypeTemplateParmDecl *NTTP = dyn_cast(D)) { assert(NTTP->getDepth() == 0 && "No nested templates yet"); - const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()]; + // If the corresponding template argument is NULL or non-existent, it's + // because we are performing instantiation from explicitly-specified + // template arguments in a function template, but there were some + // arguments left unspecified. + if (NTTP->getPosition() >= TemplateArgs.size() || + TemplateArgs[NTTP->getPosition()].isNull()) + return SemaRef.Owned(E); // FIXME: Clone the expression! + + const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()]; + // The template argument itself might be an expression, in which // case we just return that expression. if (Arg.getKind() == TemplateArgument::Expression) @@ -156,18 +193,15 @@ TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) { false, false)); } - ValueDecl *NewD - = dyn_cast_or_null(SemaRef.InstantiateCurrentDeclRef(D)); - if (!NewD) + NamedDecl *InstD = SemaRef.InstantiateCurrentDeclRef(D); + if (!InstD) return SemaRef.ExprError(); - // FIXME: Build QualifiedDeclRefExpr? - QualType T = NewD->getType(); - return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(NewD, - T.getNonReferenceType(), - E->getLocation(), - T->isDependentType(), - T->isDependentType())); + // FIXME: nested-name-specifier for QualifiedDeclRefExpr + return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD, + /*FIXME:*/false, + /*FIXME:*/0, + /*FIXME:*/false); } Sema::OwningExprResult @@ -525,8 +559,7 @@ TemplateExprInstantiator::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { const IdentifierInfo &Name = SemaRef.Context.Idents.get("__builtin_shufflevector"); TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl(); - DeclContext::lookup_result Lookup - = TUDecl->lookup(SemaRef.Context, DeclarationName(&Name)); + DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name)); assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?"); // Build a reference to the __builtin_shufflevector builtin diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index c6bcdc36f132..3756df870c2c 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/Parse/DeclSpec.h" +#include "llvm/ADT/SmallPtrSet.h" using namespace clang; /// \brief Perform adjustment on the parameter type of a function. @@ -89,8 +90,8 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, case DeclSpec::TST_unspecified: // "" is an objc qualified ID with a missing id. if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) { - Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ, - DS.getNumProtocolQualifiers()); + Result = Context.getObjCObjectPointerType(0, (ObjCProtocolDecl**)PQ, + DS.getNumProtocolQualifiers()); break; } @@ -200,8 +201,8 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, DS.getNumProtocolQualifiers()); else if (Result == Context.getObjCIdType()) // id - Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ, - DS.getNumProtocolQualifiers()); + Result = Context.getObjCObjectPointerType(0, (ObjCProtocolDecl**)PQ, + DS.getNumProtocolQualifiers()); else if (Result == Context.getObjCClassType()) { if (DeclLoc.isInvalid()) DeclLoc = DS.getSourceRange().getBegin(); @@ -242,7 +243,11 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, Expr *E = static_cast(DS.getTypeRep()); assert(E && "Didn't get an expression for decltype?"); // TypeQuals handled by caller. - Result = Context.getDecltypeType(E); + Result = BuildDecltypeType(E); + if (Result.isNull()) { + Result = Context.IntTy; + isInvalid = true; + } break; } case DeclSpec::TST_auto: { @@ -693,7 +698,7 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, // C++ 8.3.3p3: A pointer to member shall not pointer to ... a member // with reference type, or "cv void." if (T->isReferenceType()) { - Diag(Loc, diag::err_illegal_decl_pointer_to_reference) + Diag(Loc, diag::err_illegal_decl_mempointer_to_reference) << (Entity? Entity.getAsString() : "type name"); return QualType(); } @@ -814,9 +819,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip, case Declarator::KNRTypeListContext: assert(0 && "K&R type lists aren't allowed in C++"); break; - default: - printf("context: %d\n", D.getContext()); - assert(0); case Declarator::PrototypeContext: Error = 0; // Function prototype break; @@ -1062,6 +1064,13 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip, break; } case DeclaratorChunk::MemberPointer: + // Verify that we're not building a pointer to pointer to function with + // exception specification. + if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { + Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); + D.setInvalidType(true); + // Build the type anyway. + } // The scope spec must refer to a class, or be dependent. QualType ClsType; if (isDependentScopeSpecifier(DeclType.Mem.Scope())) { @@ -1186,6 +1195,45 @@ bool Sema::CheckDistantExceptionSpec(QualType T) { return FnT->hasExceptionSpec(); } +/// CheckEquivalentExceptionSpec - Check if the two types have equivalent +/// exception specifications. Exception specifications are equivalent if +/// they allow exactly the same set of exception types. It does not matter how +/// that is achieved. See C++ [except.spec]p2. +bool Sema::CheckEquivalentExceptionSpec( + const FunctionProtoType *Old, SourceLocation OldLoc, + const FunctionProtoType *New, SourceLocation NewLoc) { + bool OldAny = !Old->hasExceptionSpec() || Old->hasAnyExceptionSpec(); + bool NewAny = !New->hasExceptionSpec() || New->hasAnyExceptionSpec(); + if (OldAny && NewAny) + return false; + if (OldAny || NewAny) { + Diag(NewLoc, diag::err_mismatched_exception_spec); + Diag(OldLoc, diag::note_previous_declaration); + return true; + } + + bool Success = true; + // Both have a definite exception spec. Collect the first set, then compare + // to the second. + llvm::SmallPtrSet Types; + for (FunctionProtoType::exception_iterator I = Old->exception_begin(), + E = Old->exception_end(); I != E; ++I) + Types.insert(Context.getCanonicalType(*I).getTypePtr()); + + for (FunctionProtoType::exception_iterator I = New->exception_begin(), + E = New->exception_end(); I != E && Success; ++I) + Success = Types.erase(Context.getCanonicalType(*I).getTypePtr()); + + Success = Success && Types.empty(); + + if (Success) { + return false; + } + Diag(NewLoc, diag::err_mismatched_exception_spec); + Diag(OldLoc, diag::note_previous_declaration); + return true; +} + /// ObjCGetTypeForMethodDefinition - Builds the type for a method definition /// declarator QualType Sema::ObjCGetTypeForMethodDefinition(DeclPtrTy D) { @@ -1466,3 +1514,16 @@ QualType Sema::getQualifiedNameType(const CXXScopeSpec &SS, QualType T) { = static_cast(SS.getScopeRep()); return Context.getQualifiedNameType(NNS, T); } + +QualType Sema::BuildTypeofExprType(Expr *E) { + return Context.getTypeOfExprType(E); +} + +QualType Sema::BuildDecltypeType(Expr *E) { + if (E->getType() == Context.OverloadTy) { + Diag(E->getLocStart(), + diag::err_cannot_determine_declared_type_of_overloaded_function); + return QualType(); + } + return Context.getDecltypeType(E); +} -- cgit v1.2.3