aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-06-22 08:08:35 +0000
committerEd Schouten <ed@FreeBSD.org>2009-06-22 08:08:35 +0000
commitb897c8660c4ff7037dde81b9645737bc1c992abe (patch)
treeb6403365e77095a79062d3379c9e6aea0df5f088 /lib/Sema/SemaDecl.cpp
parent7ef7bab7e3d06f660b059b903c231f100bb13cc5 (diff)
downloadsrc-b897c8660c4ff7037dde81b9645737bc1c992abe.tar.gz
src-b897c8660c4ff7037dde81b9645737bc1c992abe.zip
Update Clang sources to r73879.vendor/clang/clang-r73879
Notes
Notes: svn path=/vendor/clang/dist/; revision=194613 svn path=/vendor/clang/clang-r73879/; revision=194615; tag=vendor/clang/clang-r73879
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp139
1 files changed, 97 insertions, 42 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index b995717ac87c..06fd1a17362a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -183,7 +183,7 @@ DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {
DeclContext *Sema::getContainingDC(DeclContext *DC) {
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) {
// A C++ out-of-line method will return to the file declaration context.
- if (MD->isOutOfLineDefinition())
+ if (MD->isOutOfLine())
return MD->getLexicalDeclContext();
// A C++ inline method is parsed *after* the topmost class it was declared
@@ -219,6 +219,27 @@ void Sema::PopDeclContext() {
CurContext = getContainingDC(CurContext);
}
+/// EnterDeclaratorContext - Used when we must lookup names in the context
+/// of a declarator's nested name specifier.
+void Sema::EnterDeclaratorContext(Scope *S, DeclContext *DC) {
+ assert(PreDeclaratorDC == 0 && "Previous declarator context not popped?");
+ PreDeclaratorDC = static_cast<DeclContext*>(S->getEntity());
+ CurContext = DC;
+ assert(CurContext && "No context?");
+ S->setEntity(CurContext);
+}
+
+void Sema::ExitDeclaratorContext(Scope *S) {
+ S->setEntity(PreDeclaratorDC);
+ PreDeclaratorDC = 0;
+
+ // Reset CurContext to the nearest enclosing context.
+ while (!S->getEntity() && S->getParent())
+ S = S->getParent();
+ CurContext = static_cast<DeclContext*>(S->getEntity());
+ assert(CurContext && "No context?");
+}
+
/// \brief Determine whether we allow overloading of the function
/// PrevDecl with another declaration.
///
@@ -235,7 +256,7 @@ static bool AllowOverloadingOfFunction(Decl *PrevDecl, ASTContext &Context) {
if (isa<OverloadedFunctionDecl>(PrevDecl))
return true;
- return PrevDecl->getAttr<OverloadableAttr>() != 0;
+ return PrevDecl->getAttr<OverloadableAttr>(Context) != 0;
}
/// Add this decl to the scope shadowed decl chains.
@@ -590,8 +611,9 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
/// DeclhasAttr - returns true if decl Declaration already has the target
/// attribute.
-static bool DeclHasAttr(const Decl *decl, const Attr *target) {
- for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
+static bool
+DeclHasAttr(ASTContext &Context, const Decl *decl, const Attr *target) {
+ for (const Attr *attr = decl->getAttrs(Context); attr; attr = attr->getNext())
if (attr->getKind() == target->getKind())
return true;
@@ -600,11 +622,11 @@ static bool DeclHasAttr(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(); attr; attr = attr->getNext()) {
- if (!DeclHasAttr(New, attr) && attr->isMerged()) {
+ for (const Attr *attr = Old->getAttrs(C); attr; attr = attr->getNext()) {
+ if (!DeclHasAttr(C, New, attr) && attr->isMerged()) {
Attr *NewAttr = attr->clone(C);
NewAttr->setInherited(true);
- New->addAttr(NewAttr);
+ New->addAttr(C, NewAttr);
}
}
}
@@ -1615,7 +1637,7 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
NewTD->setInvalidDecl();
// Handle attributes prior to checking for duplicates in MergeVarDecl
- ProcessDeclAttributes(NewTD, D);
+ ProcessDeclAttributes(S, NewTD, D);
// Merge the decl with the existing one if appropriate. If the decl is
// in an outer scope, it isn't the same thing.
if (PrevDecl && isDeclInScope(PrevDecl, DC, S)) {
@@ -1801,13 +1823,14 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
NewVD->setLexicalDeclContext(CurContext);
// Handle attributes prior to checking for duplicates in MergeVarDecl
- ProcessDeclAttributes(NewVD, D);
+ ProcessDeclAttributes(S, NewVD, D);
// Handle GNU asm-label extension (encoded as an attribute).
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewVD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
+ NewVD->addAttr(Context,
+ ::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -1886,11 +1909,11 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
}
if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
- && !NewVD->hasAttr<BlocksAttr>())
+ && !NewVD->hasAttr<BlocksAttr>(Context))
Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
bool isVM = T->isVariablyModifiedType();
- if (isVM || NewVD->hasAttr<CleanupAttr>())
+ if (isVM || NewVD->hasAttr<CleanupAttr>(Context))
CurFunctionNeedsScopeChecking = true;
if ((isVM && NewVD->hasLinkage()) ||
@@ -1945,12 +1968,12 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
return NewVD->setInvalidDecl();
}
- if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>()) {
+ if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>(Context)) {
Diag(NewVD->getLocation(), diag::err_block_on_nonlocal);
return NewVD->setInvalidDecl();
}
- if (isVM && NewVD->hasAttr<BlocksAttr>()) {
+ if (isVM && NewVD->hasAttr<BlocksAttr>(Context)) {
Diag(NewVD->getLocation(), diag::err_block_on_vm);
return NewVD->setInvalidDecl();
}
@@ -2180,7 +2203,8 @@ 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(::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
+ NewFD->addAttr(Context,
+ ::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -2260,7 +2284,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
<< D.getCXXScopeSpec().getRange();
NewFD->setInvalidDecl();
- } else if (!Redeclaration) {
+ } else if (!Redeclaration && (!PrevDecl || !isa<UsingDecl>(PrevDecl))) {
// The user tried to provide an out-of-line definition for a
// function that is a member of a class or namespace, but there
// was no such member function declared (C++ [class.mfct]p2,
@@ -2298,10 +2322,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// (for example to check for conflicts, etc).
// FIXME: This needs to happen before we merge declarations. Then,
// let attribute merging cope with attribute conflicts.
- ProcessDeclAttributes(NewFD, D);
+ ProcessDeclAttributes(S, NewFD, D);
AddKnownFunctionAttributes(NewFD);
- if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
+ if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>(Context)) {
// 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)
@@ -2309,7 +2333,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (PrevDecl)
Diag(PrevDecl->getLocation(),
diag::note_attribute_overloadable_prev_overload);
- NewFD->addAttr(::new (Context) OverloadableAttr());
+ NewFD->addAttr(Context, ::new (Context) OverloadableAttr());
}
// If this is a locally-scoped extern C function, update the
@@ -2431,7 +2455,8 @@ void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
if (PrevDecl &&
(!AllowOverloadingOfFunction(PrevDecl, Context) ||
- !IsOverload(NewFD, PrevDecl, MatchedDecl))) {
+ !IsOverload(NewFD, PrevDecl, MatchedDecl)) &&
+ !isa<UsingDecl>(PrevDecl)) {
Redeclaration = true;
Decl *OldDecl = PrevDecl;
@@ -2708,8 +2733,12 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) {
IK_Default);
if (!Constructor)
Var->setInvalidDecl();
- else if (!RD->hasTrivialConstructor())
- InitializeVarWithConstructor(Var, Constructor, InitType, 0, 0);
+ else {
+ if (!RD->hasTrivialConstructor())
+ InitializeVarWithConstructor(Var, Constructor, InitType, 0, 0);
+ // Check for valid construction.
+ DefineImplicitDefaultConstructor(Var->getLocation(), Constructor);
+ }
}
}
@@ -2907,9 +2936,9 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
if (II)
IdResolver.AddDecl(New);
- ProcessDeclAttributes(New, D);
+ ProcessDeclAttributes(S, New, D);
- if (New->hasAttr<BlocksAttr>()) {
+ if (New->hasAttr<BlocksAttr>(Context)) {
Diag(New->getLocation(), diag::err_block_on_nonlocal);
}
return DeclPtrTy::make(New);
@@ -3035,9 +3064,10 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
// Checking attributes of current function definition
// dllimport attribute.
- if (FD->getAttr<DLLImportAttr>() && (!FD->getAttr<DLLExportAttr>())) {
+ if (FD->getAttr<DLLImportAttr>(Context) &&
+ (!FD->getAttr<DLLExportAttr>(Context))) {
// dllimport attribute cannot be applied to definition.
- if (!(FD->getAttr<DLLImportAttr>())->isInherited()) {
+ if (!(FD->getAttr<DLLImportAttr>(Context))->isInherited()) {
Diag(FD->getLocation(),
diag::err_attribute_can_be_applied_only_to_symbol_declaration)
<< "dllimport";
@@ -3065,10 +3095,23 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
Stmt *Body = BodyArg.takeAs<Stmt>();
if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(dcl)) {
FD->setBody(Body);
+
+ if (!FD->isInvalidDecl())
+ DiagnoseUnusedParameters(FD->param_begin(), FD->param_end());
+
+ // C++ [basic.def.odr]p2:
+ // [...] A virtual member function is used if it is not pure. [...]
+ if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD))
+ if (Method->isVirtual() && !Method->isPure())
+ MarkDeclarationReferenced(Method->getLocation(), Method);
+
assert(FD == getCurFunctionDecl() && "Function parsing confused");
} else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {
assert(MD == getCurMethodDecl() && "Method parsing confused");
MD->setBody(Body);
+
+ if (!MD->isInvalidDecl())
+ DiagnoseUnusedParameters(MD->param_begin(), MD->param_end());
} else {
Body->Destroy(Context);
return DeclPtrTy();
@@ -3206,8 +3249,9 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
unsigned FormatIdx;
bool HasVAListArg;
if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
- if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr("printf", FormatIdx + 1,
+ if (!FD->getAttr<FormatAttr>(Context))
+ FD->addAttr(Context,
+ ::new (Context) FormatAttr("printf", FormatIdx + 1,
HasVAListArg ? 0 : FormatIdx + 2));
}
@@ -3216,8 +3260,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>())
- FD->addAttr(::new (Context) ConstAttr());
+ if (!FD->getAttr<ConstAttr>(Context))
+ FD->addAttr(Context, ::new (Context) ConstAttr());
}
}
@@ -3235,15 +3279,17 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
return;
if (Name->isStr("NSLog") || Name->isStr("NSLogv")) {
- if (const FormatAttr *Format = FD->getAttr<FormatAttr>()) {
+ if (const FormatAttr *Format = FD->getAttr<FormatAttr>(Context)) {
// FIXME: We known better than our headers.
const_cast<FormatAttr *>(Format)->setType("printf");
} else
- FD->addAttr(::new (Context) FormatAttr("printf", 1,
+ FD->addAttr(Context,
+ ::new (Context) FormatAttr("printf", 1,
Name->isStr("NSLogv") ? 0 : 2));
} else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
- if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr("printf", 2,
+ if (!FD->getAttr<FormatAttr>(Context))
+ FD->addAttr(Context,
+ ::new (Context) FormatAttr("printf", 2,
Name->isStr("vasprintf") ? 0 : 3));
}
}
@@ -3599,7 +3645,7 @@ CreateNewDecl:
// the #pragma tokens are effectively skipped over during the
// parsing of the struct).
if (unsigned Alignment = getPragmaPackAlignment())
- New->addAttr(::new (Context) PackedAttr(Alignment * 8));
+ New->addAttr(Context, ::new (Context) PackedAttr(Alignment * 8));
}
if (getLangOptions().CPlusPlus && SS.isEmpty() && Name && !Invalid) {
@@ -3628,7 +3674,7 @@ CreateNewDecl:
New->setInvalidDecl();
if (Attr)
- ProcessDeclAttributeList(New, Attr);
+ ProcessDeclAttributeList(S, New, Attr);
// If we're declaring or defining a tag in function prototype scope
// in C, note that this type can only be used within the function.
@@ -3786,6 +3832,14 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
NamedDecl *PrevDecl = LookupName(S, II, LookupMemberName, true);
+
+ if (PrevDecl && PrevDecl->isTemplateParameter()) {
+ // Maybe we will complain about the shadowed template parameter.
+ DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
+ // Just pretend that we didn't see the previous declaration.
+ PrevDecl = 0;
+ }
+
if (PrevDecl && !isDeclInScope(PrevDecl, Record, S))
PrevDecl = 0;
@@ -3878,7 +3932,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
// FIXME: We need to pass in the attributes given an AST
// representation, not a parser representation.
if (D)
- ProcessDeclAttributes(NewFD, *D);
+ // FIXME: What to pass instead of TUScope?
+ ProcessDeclAttributes(TUScope, NewFD, *D);
if (T.isObjCGCWeak())
Diag(Loc, diag::warn_attribute_weak_on_field);
@@ -3985,7 +4040,7 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
}
// Process attributes attached to the ivar.
- ProcessDeclAttributes(NewID, D);
+ ProcessDeclAttributes(S, NewID, D);
if (D.isInvalidType())
NewID->setInvalidDecl();
@@ -4151,7 +4206,7 @@ void Sema::ActOnFields(Scope* S,
}
if (Attr)
- ProcessDeclAttributeList(Record, Attr);
+ ProcessDeclAttributeList(S, Record, Attr);
}
EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
@@ -4441,7 +4496,7 @@ void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
// FIXME: This implementation is an ugly hack!
if (PrevDecl) {
- PrevDecl->addAttr(::new (Context) WeakAttr());
+ PrevDecl->addAttr(Context, ::new (Context) WeakAttr());
return;
}
Diag(PragmaLoc, diag::err_unsupported_pragma_weak);
@@ -4457,8 +4512,8 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name,
// FIXME: This implementation is an ugly hack!
if (PrevDecl) {
- PrevDecl->addAttr(::new (Context) AliasAttr(AliasName->getName()));
- PrevDecl->addAttr(::new (Context) WeakAttr());
+ PrevDecl->addAttr(Context, ::new (Context) AliasAttr(AliasName->getName()));
+ PrevDecl->addAttr(Context, ::new (Context) WeakAttr());
return;
}
Diag(PragmaLoc, diag::err_unsupported_pragma_weak);