aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-07-04 13:58:54 +0000
committerEd Schouten <ed@FreeBSD.org>2009-07-04 13:58:54 +0000
commit5362a71c02e7d448a8ce98cf00c47e353fba5d04 (patch)
tree8ddfe382e1c6d590dc240e76f7cd45cea5c78e24 /lib/Sema
parent4ebdf5c4f587daef4e0be499802eac3a7a49bf2f (diff)
downloadsrc-5362a71c02e7d448a8ce98cf00c47e353fba5d04.tar.gz
src-5362a71c02e7d448a8ce98cf00c47e353fba5d04.zip
Import Clang r74788.vendor/clang/clang-r74788
Notes
Notes: svn path=/vendor/clang/dist/; revision=195341 svn path=/vendor/clang/clang-r74788/; revision=195343; tag=vendor/clang/clang-r74788
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/JumpDiagnostics.cpp6
-rw-r--r--lib/Sema/Sema.cpp4
-rw-r--r--lib/Sema/Sema.h92
-rw-r--r--lib/Sema/SemaAttr.cpp2
-rw-r--r--lib/Sema/SemaChecking.cpp55
-rw-r--r--lib/Sema/SemaDecl.cpp93
-rw-r--r--lib/Sema/SemaDeclAttr.cpp111
-rw-r--r--lib/Sema/SemaDeclCXX.cpp168
-rw-r--r--lib/Sema/SemaDeclObjC.cpp155
-rw-r--r--lib/Sema/SemaExpr.cpp575
-rw-r--r--lib/Sema/SemaExprCXX.cpp8
-rw-r--r--lib/Sema/SemaExprObjC.cpp34
-rw-r--r--lib/Sema/SemaInherit.cpp4
-rw-r--r--lib/Sema/SemaInit.cpp29
-rw-r--r--lib/Sema/SemaLookup.cpp42
-rw-r--r--lib/Sema/SemaOverload.cpp72
-rw-r--r--lib/Sema/SemaStmt.cpp6
-rw-r--r--lib/Sema/SemaTemplate.cpp55
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp134
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp102
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp124
-rw-r--r--lib/Sema/SemaTemplateInstantiateExpr.cpp59
-rw-r--r--lib/Sema/SemaType.cpp79
23 files changed, 1288 insertions, 721 deletions
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<VarDecl>(D)) {
if (VD->getType()->isVariablyModifiedType())
return diag::note_protected_by_vla;
- if (VD->hasAttr<CleanupAttr>(Context))
+ if (VD->hasAttr<CleanupAttr>())
return diag::note_protected_by_cleanup;
} else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(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 <deque>
#include <list>
#include <string>
-#include <queue>
#include <vector>
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<UnusedAttr>(Context))
+ !(*Param)->template hasAttr<UnusedAttr>())
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<FunctionDecl *, 16> FunctionSet;
+ typedef llvm::SmallPtrSet<AnyFunctionDecl, 16> FunctionSet;
typedef llvm::SmallPtrSet<NamespaceDecl *, 16> AssociatedNamespaceSet;
typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> 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<PendingImplicitInstantiation> PendingImplicitInstantiations;
+ std::deque<PendingImplicitInstantiation> 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<FormatAttr>(Context)) {
+ if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
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<NonNullAttr>(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<FormatAttr>(Context);
+ const FormatAttr *Format = NDecl->getAttr<FormatAttr>();
if (!Format)
return move(TheCallResult);
const VarDecl *V = dyn_cast<VarDecl>(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<ConditionalOperator>(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<ParmVarDecl>(VD))
+ return true;
}
return false;
@@ -774,7 +794,7 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
= dyn_cast<ImplicitCastExpr>(CE->getCallee())) {
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
- if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>(Context)) {
+ if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>()) {
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<DeclRefExpr>(OrigFormatExpr))
- if (isa<ParmVarDecl>(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<OverloadedFunctionDecl>(PrevDecl))
return true;
- return PrevDecl->getAttr<OverloadableAttr>(Context) != 0;
+ return PrevDecl->getAttr<OverloadableAttr>() != 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<FieldDecl>(*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<StringLiteral>(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<BlocksAttr>(Context))
+ && !NewVD->hasAttr<BlocksAttr>())
Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
bool isVM = T->isVariablyModifiedType();
- if (isVM || NewVD->hasAttr<CleanupAttr>(Context))
+ if (isVM || NewVD->hasAttr<CleanupAttr>())
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<BlocksAttr>(Context)) {
+ if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>()) {
Diag(NewVD->getLocation(), diag::err_block_on_nonlocal);
return NewVD->setInvalidDecl();
}
- if (isVM && NewVD->hasAttr<BlocksAttr>(Context)) {
+ if (isVM && NewVD->hasAttr<BlocksAttr>()) {
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<StringLiteral>(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<OverloadableAttr>(Context)) {
+ if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
// 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<BlocksAttr>(Context)) {
+ if (New->hasAttr<BlocksAttr>()) {
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<DLLImportAttr>(Context) &&
- (!FD->getAttr<DLLExportAttr>(Context))) {
+ if (FD->getAttr<DLLImportAttr>() &&
+ (!FD->getAttr<DLLExportAttr>())) {
// dllimport attribute cannot be applied to definition.
- if (!(FD->getAttr<DLLImportAttr>(Context))->isInherited()) {
+ if (!(FD->getAttr<DLLImportAttr>())->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<FormatAttr>(Context))
- FD->addAttr(Context,
- ::new (Context) FormatAttr("printf", FormatIdx + 1,
+ if (!FD->getAttr<FormatAttr>())
+ 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<ConstAttr>(Context))
- FD->addAttr(Context, ::new (Context) ConstAttr());
+ if (!FD->getAttr<ConstAttr>())
+ 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<FormatAttr>(Context)) {
+ if (const FormatAttr *Format = FD->getAttr<FormatAttr>()) {
// FIXME: We known better than our headers.
const_cast<FormatAttr *>(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<FormatAttr>(Context))
- FD->addAttr(Context,
- ::new (Context) FormatAttr("printf", 2,
+ if (!FD->getAttr<FormatAttr>())
+ 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<TagDecl>(d))
- TD->addAttr(S.Context, ::new (S.Context) PackedAttr(1));
+ TD->addAttr(::new (S.Context) PackedAttr(1));
else if (FieldDecl *FD = dyn_cast<FieldDecl>(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<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(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<VarDecl>(D)) {
isDef = (!VD->hasExternalStorage() || VD->getInit());
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- isDef = FD->getBody(S.Context);
+ isDef = FD->getBody();
} else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(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<VarDecl>(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<DLLExportAttr>(S.Context)) {
+ if (D->getAttr<DLLExportAttr>()) {
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<VarDecl>(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<FastCallAttr>(S.Context)) {
+ if (d->getAttr<FastCallAttr>()) {
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<StdCallAttr>(S.Context)) {
+ if (d->getAttr<StdCallAttr>()) {
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<FieldDecl>(*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<FieldDecl>(*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::DenseMap<void*, CXXBaseOrMemberInitializer *>Members;
+ bool err = false;
+ for (unsigned i = 0; i < NumMemInits; i++) {
+ CXXBaseOrMemberInitializer *Member =
+ static_cast<CXXBaseOrMemberInitializer*>(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<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion())
+ KeyToMember = static_cast<void *>(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<CXXBaseOrMemberInitializer **>(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<CXXMethodDecl>(*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<DeclContext*>(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<CXXRecordDecl>(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<CXXRecordDecl>(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<CXXRecordDecl>(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<CXXRecordDecl>(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<CXXRecordDecl>(
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<CXXConstructorDecl>(*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<ObjCCategoryDecl*>(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<Selector, const ObjCMethodDecl*> 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<ObjCMethodDecl>(CurContext)) {
if (ObjCImplementationDecl *IMD =
dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) {
- if (IMD->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (IMD->getInstanceMethod(PDecl->getSetterName()))
return false;
}
else if (ObjCCategoryImplDecl *CIMD =
dyn_cast<ObjCCategoryImplDecl>(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<Selector> &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<Selector> &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<Selector> &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<Selector> &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<ObjCInterfaceDecl>(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<Selector> 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<ObjCImplementationDecl>(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<ObjCCategoryImplDecl>(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<DeclContext>(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<FieldDecl>(FD), S);
else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>()))
- 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<DeprecatedAttr>(Context)) {
+ if (D->getAttr<DeprecatedAttr>()) {
// 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<DeprecatedAttr>(Context);
+ isSilenced = ND->getAttr<DeprecatedAttr>();
// 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<ObjCImplementationDecl>(MD->getParent())) {
- MD = Impl->getClassInterface()->getMethod(Context,
- MD->getSelector(),
+ MD = Impl->getClassInterface()->getMethod(MD->getSelector(),
MD->isInstanceMethod());
- isSilenced |= MD && MD->getAttr<DeprecatedAttr>(Context);
+ isSilenced |= MD && MD->getAttr<DeprecatedAttr>();
}
}
}
@@ -80,7 +79,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
}
// See if the decl is unavailable
- if (D->getAttr<UnavailableAttr>(Context)) {
+ if (D->getAttr<UnavailableAttr>()) {
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<SentinelAttr>(Context);
+ const SentinelAttr *attr = D->getAttr<SentinelAttr>();
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<VarDecl>(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<FunctionDecl>(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<FunctionDecl>(VD)) && DiagnoseUseOfDecl(VD, Loc))
return ExprError();
- if (VarDecl *Var = dyn_cast<VarDecl>(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<FunctionDecl>(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<BlocksAttr>(Context))
+ if (VD->getAttr<BlocksAttr>())
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<ImplicitCastExpr>(FnExpr))
FnExpr = IcExpr->getSubExpr();
@@ -2639,14 +2654,41 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
cast<UnaryOperator>(FnExpr)->getOpcode()
== UnaryOperator::AddrOf) {
FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr();
- } else if ((DRExpr = dyn_cast<DeclRefExpr>(FnExpr))) {
+ } else if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(FnExpr)) {
// Qualified names disable ADL (C++0x [basic.lookup.argdep]p1).
ADL &= !isa<QualifiedDeclRefExpr>(DRExpr);
+ NDecl = dyn_cast<NamedDecl>(DRExpr->getDecl());
break;
} else if (UnresolvedFunctionNameExpr *DepName
= dyn_cast<UnresolvedFunctionNameExpr>(FnExpr)) {
UnqualifiedName = DepName->getName();
break;
+ } else if (TemplateIdRefExpr *TemplateIdRef
+ = dyn_cast<TemplateIdRefExpr>(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<FunctionDecl>(DRExpr->getDecl());
- if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DRExpr->getDecl())))
+ if (NDecl) {
+ FDecl = dyn_cast<FunctionDecl>(NDecl);
+ if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(NDecl)))
FDecl = FunctionTemplate->getTemplatedDecl();
else
- FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
- Ovl = dyn_cast<OverloadedFunctionDecl>(DRExpr->getDecl());
- NDecl = dyn_cast<NamedDecl>(DRExpr->getDecl());
+ FDecl = dyn_cast<FunctionDecl>(NDecl);
+ Ovl = dyn_cast<OverloadedFunctionDecl>(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<QualifiedDeclRefExpr>(DRExpr))
+ = dyn_cast<QualifiedDeclRefExpr>(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<xx>" 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<xx>" 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 -> <n x 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<TransparentUnionAttr>(Context))
+ if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
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<IntegerLiteral>(rex)) ||
- (eltType->isFloatingType() && isa<FloatingLiteral>(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<IntegerLiteral>(lex)) ||
- (eltType->isFloatingType() && isa<FloatingLiteral>(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<SentinelAttr>(Context)) {
+ if (CurBlock->TheDecl->getAttr<SentinelAttr>()) {
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<SentinelAttr>(Context)) {
+ CurBlock->TheDecl->getAttr<SentinelAttr>()) {
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<FunctionDecl>(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<FunctionDecl>(*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<foo>", 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<CXXMethodDecl>(*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<RecordDecl>(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<OverloadableAttr>(Context)) {
+ if ((*I)->getAttr<OverloadableAttr>()) {
// 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<FunctionDecl>(*Op))
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op)) {
if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
Functions.insert(FD); // FIXME: canonical FD
+ } else if (FunctionTemplateDecl *FunTmpl
+ = dyn_cast<FunctionTemplateDecl>(*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<FunctionDecl>(*I);
- if (!Func)
- break;
-
- Functions.insert(Func);
+ for (llvm::tie(I, E) = (*NS)->lookup(Name); I != E; ++I) {
+ if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*I))
+ Functions.insert(Func);
+ else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*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<FunctionDecl>(*I);
- if (!Func)
- break;
-
- Functions.insert(Func);
+ if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*I))
+ Functions.insert(Func);
+ else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*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<CXXConstructorDecl>(*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<FunctionDecl>(*F))
+ AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
+ SuppressUserConversions);
+ else
+ AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*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<CXXMethodDecl>(*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<FunctionDecl>(*Func))
+ AddOverloadCandidate(FD, Args, NumArgs, CandidateSet);
+ else
+ AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*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<UnavailableAttr>(Context)))
+ Best->Function->getAttr<UnavailableAttr>()))
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<UnavailableAttr>(Context)) {
+ Cand->Function->getAttr<UnavailableAttr>()) {
// 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<FunctionDecl>(*Func)) {
+ if (HasExplicitTemplateArgs)
+ continue;
+
AddOverloadCandidate(FunDecl, Args, NumArgs, CandidateSet);
Ctx = FunDecl->getDeclContext();
} else {
FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*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<FunctionDecl>(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<FunctionTemplateDecl>(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<CXXMethodDecl>(*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<CXXMethodDecl>(*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<NoReturnAttr>(Context)) {
+ if (CurBlock->TheDecl->hasAttr<NoReturnAttr>()) {
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<NoReturnAttr>(Context))
+ if (FD->hasAttr<NoReturnAttr>())
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<TemplateName>();
+
+ // Translate the parser's template argument list in our AST format.
+ llvm::SmallVector<TemplateArgument, 16> 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<TemplateArgument, 4> 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<TemplateArgument, 4> Deduced;
+ llvm::SmallVector<QualType, 4> 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<FunctionDecl>(
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
@@ -100,6 +100,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<uintptr_t>(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,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
@@ -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<uintptr_t>(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<ActiveTemplateInstantiation, 16>::reverse_iterator
Active = ActiveTemplateInstantiations.rbegin(),
ActiveEnd = ActiveTemplateInstantiations.rend();
@@ -183,7 +208,7 @@ void Sema::PrintInstantiationStack() {
TemplateDecl *Template = cast<TemplateDecl>((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<ClassTemplatePartialSpecializationDecl>((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<FunctionTemplateDecl>((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<ClassTemplatePartialSpecializationDecl>(
+ (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<FunctionTemplateDecl>((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<Expr>());
+ return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
}
QualType
@@ -555,7 +594,7 @@ TemplateTypeInstantiator::InstantiateDecltypeType(const DecltypeType *T) const {
if (E.isInvalid())
return QualType();
- return SemaRef.Context.getDecltypeType(E.takeAs<Expr>());
+ return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
}
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<DeclPtrTy, 4> 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<FunctionDecl>(*D)) {
- if (!Function->getBody(Context))
+ if (!Function->getBody())
InstantiateFunctionDefinition(PointOfInstantiation, Function);
} else if (VarDecl *Var = dyn_cast<VarDecl>(*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<Sema::DeclPtrTy, 4> 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<FunctionTemplateDecl>((Decl *)ActiveInst.Entity)) {
+ assert(FunTmpl->getTemplatedDecl() == Tmpl &&
+ "Deduction from the wrong function template?");
+ ActiveInst.Kind = ActiveInstType::TemplateInstantiation;
+ ActiveInst.Entity = reinterpret_cast<uintptr_t>(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<PendingImplicitInstantiation> 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<FunctionDecl>(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
@@ -107,12 +107,49 @@ TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr(
}
Sema::OwningExprResult
+TemplateExprInstantiator::VisitTemplateIdRefExpr(TemplateIdRefExpr *E) {
+ TemplateName Template
+ = SemaRef.InstantiateTemplateName(E->getTemplateName(), E->getTemplateNameLoc(),
+ TemplateArgs);
+ // FIXME: Can InstantiateTemplateName report an error?
+
+ llvm::SmallVector<TemplateArgument, 4> 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<NonTypeTemplateParmDecl>(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<ValueDecl>(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:
// "<proto1,proto2>" 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<protocol-list>
- 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<Expr *>(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<const Type*, 8> 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<NestedNameSpecifier *>(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);
+}