Newer
Older
//===--- SemaDecl.cpp - Semantic Analysis for Declarations ----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements semantic analysis for declarations.
//
//===----------------------------------------------------------------------===//
Chris Lattner
committed
#include "Sema.h"
Anders Carlsson
committed
#include "clang/AST/APValue.h"
#include "clang/AST/ASTConsumer.h"
Chris Lattner
committed
#include "clang/AST/ASTContext.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/SourceManager.h"
// FIXME: layering (ideally, Sema shouldn't be dependent on Lex API's)
#include "clang/Lex/Preprocessor.h"
using namespace clang;
Argyrios Kyrtzidis
committed
Sema::TypeTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) {
Douglas Gregor
committed
if (IIDecl && (isa<TypedefDecl>(IIDecl) ||
isa<ObjCInterfaceDecl>(IIDecl) ||
isa<TagDecl>(IIDecl)))
return IIDecl;
Chris Lattner
committed
}
DeclContext *Sema::getDCParent(DeclContext *DC) {
// If CurContext is a ObjC method, getParent() will return NULL.
if (isa<ObjCMethodDecl>(DC))
return Context.getTranslationUnitDecl();
// A C++ inline method is parsed *after* the topmost class it was declared in
// is fully parsed (it's "complete").
// The parsing of a C++ inline method happens at the declaration context of
// the topmost (non-nested) class it is declared in.
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) {
assert(isa<CXXRecordDecl>(MD->getParent()) && "C++ method not in Record.");
DC = MD->getParent();
while (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC->getParent()))
DC = RD;
// Return the declaration context of the topmost class the inline method is
// declared in.
return DC;
}
return DC->getParent();
}
assert(getDCParent(DC) == CurContext &&
"The next DeclContext should be directly contained in the current one.");
void Sema::PopDeclContext() {
assert(CurContext && "DeclContext imbalance!");
CurContext = getDCParent(CurContext);
Argyrios Kyrtzidis
committed
/// Add this decl to the scope shadowed decl chains.
void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
S->AddDecl(D);
// C++ [basic.scope]p4:
// -- exactly one declaration shall declare a class name or
// enumeration name that is not a typedef name and the other
// declarations shall all refer to the same object or
// enumerator, or all refer to functions and function templates;
// in this case the class name or enumeration name is hidden.
if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
// We are pushing the name of a tag (enum or class).
Argyrios Kyrtzidis
committed
IdentifierResolver::iterator
I = IdResolver.begin(TD->getIdentifier(),
TD->getDeclContext(), false/*LookInParentCtx*/);
if (I != IdResolver.end() && isDeclInScope(*I, TD->getDeclContext(), S)) {
// There is already a declaration with the same name in the same
// scope. It must be found before we find the new declaration,
// so swap the order on the shadowed declaration chain.
Argyrios Kyrtzidis
committed
IdResolver.AddShadowedDecl(TD, *I);
return;
}
}
IdResolver.AddDecl(D);
Argyrios Kyrtzidis
committed
}
if (S->decl_empty()) return;
assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!");
for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
Decl *TmpD = static_cast<Decl*>(*I);
assert(TmpD && "This decl didn't get pushed??");
if (isa<CXXFieldDecl>(TmpD)) continue;
assert(isa<ScopedDecl>(TmpD) && "Decl isn't ScopedDecl?");
ScopedDecl *D = cast<ScopedDecl>(TmpD);
Chris Lattner
committed
IdentifierInfo *II = D->getIdentifier();
if (!II) continue;
// We only want to remove the decls from the identifier decl chains for
// local scopes, when inside a function/method.
if (S->getFnParent() != 0)
IdResolver.RemoveDecl(D);
// Chain this decl to the containing DeclContext.
D->setNext(CurContext->getDeclChain());
CurContext->setDeclChain(D);
Steve Naroff
committed
/// getObjCInterfaceDecl - Look up a for a class declaration in the scope.
/// return 0 if one not found.
ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
// The third "scope" argument is 0 since we aren't enabling lazy built-in
// creation from this context.
Decl *IDecl = LookupDecl(Id, Decl::IDNS_Ordinary, 0, false);
Fariborz Jahanian
committed
Fariborz Jahanian
committed
}
Steve Naroff
committed
/// LookupDecl - Look up the inner-most declaration in the specified
/// namespace.
Decl *Sema::LookupDecl(const IdentifierInfo *II, unsigned NSI,
Scope *S, bool enableLazyBuiltinCreation) {
if (II == 0) return 0;
Douglas Gregor
committed
unsigned NS = NSI;
if (getLangOptions().CPlusPlus && (NS & Decl::IDNS_Ordinary))
NS |= Decl::IDNS_Tag;
// Scan up the scope chain looking for a decl that matches this identifier
// that is in the appropriate namespace. This search should not take long, as
// shadowing of names is uncommon, and deep shadowing is extremely uncommon.
for (IdentifierResolver::iterator
Argyrios Kyrtzidis
committed
I = IdResolver.begin(II, CurContext), E = IdResolver.end(); I != E; ++I)
if ((*I)->getIdentifierNamespace() & NS)
return *I;
// If we didn't find a use of this identifier, and if the identifier
// corresponds to a compiler builtin, create the decl object for the builtin
// now, injecting it into translation unit scope, and return it.
Douglas Gregor
committed
if (NS & Decl::IDNS_Ordinary) {
if (enableLazyBuiltinCreation) {
// If this is a builtin on this (or all) targets, create the decl.
if (unsigned BuiltinID = II->getBuiltinID())
return LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID, S);
}
Steve Naroff
committed
if (getLangOptions().ObjC1) {
// @interface and @compatibility_alias introduce typedef-like names.
// Unlike typedef's, they can only be introduced at file-scope (and are
// therefore not scoped decls). They can, however, be shadowed by
Steve Naroff
committed
// other names in IDNS_Ordinary.
ObjCInterfaceDeclsTy::iterator IDI = ObjCInterfaceDecls.find(II);
if (IDI != ObjCInterfaceDecls.end())
return IDI->second;
Steve Naroff
committed
ObjCAliasTy::iterator I = ObjCAliasDecls.find(II);
if (I != ObjCAliasDecls.end())
return I->second->getClassInterface();
}
}
return 0;
}
void Sema::InitBuiltinVaListType() {
if (!Context.getBuiltinVaListType().isNull())
return;
IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
}
/// LazilyCreateBuiltin - The specified Builtin-ID was first used at file scope.
/// lazily create a decl for it.
ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
Scope *S) {
Builtin::ID BID = (Builtin::ID)bid;
if (Context.BuiltinInfo.hasVAListUse(BID))
InitBuiltinVaListType();
QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context);
FunctionDecl *New = FunctionDecl::Create(Context,
Context.getTranslationUnitDecl(),
SourceLocation(), II, R,
FunctionDecl::Extern, false, 0);
// Create Decl objects for each parameter, adding them to the
// FunctionDecl.
if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(R)) {
llvm::SmallVector<ParmVarDecl*, 16> Params;
for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i)
Params.push_back(ParmVarDecl::Create(Context, New, SourceLocation(), 0,
FT->getArgType(i), VarDecl::None, 0,
0));
New->setParams(&Params[0], Params.size());
}
// TUScope is the translation-unit scope to insert this function into.
PushOnScopeChains(New, TUScope);
return New;
}
/// MergeTypeDefDecl - We just parsed a typedef 'New' which has the same name
/// and scope as a previous declaration 'Old'. Figure out how to resolve this
/// situation, merging decls or emitting diagnostics as appropriate.
///
Steve Naroff
committed
TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
// Allow multiple definitions for ObjC built-in typedefs.
// FIXME: Verify the underlying types are equivalent!
if (getLangOptions().ObjC1) {
const IdentifierInfo *typeIdent = New->getIdentifier();
if (typeIdent == Ident_id) {
Context.setObjCIdType(New);
return New;
} else if (typeIdent == Ident_Class) {
Context.setObjCClassType(New);
return New;
} else if (typeIdent == Ident_SEL) {
Context.setObjCSelType(New);
return New;
} else if (typeIdent == Ident_Protocol) {
Context.setObjCProtoType(New->getUnderlyingType());
return New;
}
// Fall through - the typedef name was not a builtin type.
}
// Verify the old decl was also a typedef.
TypedefDecl *Old = dyn_cast<TypedefDecl>(OldD);
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind,
New->getName());
Diag(OldD->getLocation(), diag::err_previous_definition);
return New;
}
// If the typedef types are not identical, reject them in all languages and
// with any extensions enabled.
if (Old->getUnderlyingType() != New->getUnderlyingType() &&
Context.getCanonicalType(Old->getUnderlyingType()) !=
Context.getCanonicalType(New->getUnderlyingType())) {
Diag(New->getLocation(), diag::err_redefinition_different_typedef,
New->getUnderlyingType().getAsString(),
Old->getUnderlyingType().getAsString());
Diag(Old->getLocation(), diag::err_previous_definition);
return Old;
}
if (getLangOptions().Microsoft) return New;
// Redeclaration of a type is a constraint violation (6.7.2.3p1).
// Apparently GCC, Intel, and Sun all silently ignore the redeclaration if
// *either* declaration is in a system header. The code below implements
// this adhoc compatibility rule. FIXME: The following code will not
// work properly when compiling ".i" files (containing preprocessed output).
if (PP.getDiagnostics().getSuppressSystemWarnings()) {
SourceManager &SrcMgr = Context.getSourceManager();
if (SrcMgr.isInSystemHeader(Old->getLocation()))
return New;
if (SrcMgr.isInSystemHeader(New->getLocation()))
return New;
}
Diag(New->getLocation(), diag::err_redefinition, New->getName());
Diag(Old->getLocation(), diag::err_previous_definition);
return New;
}
/// 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())
if (attr->getKind() == target->getKind())
return true;
return false;
}
/// MergeAttributes - append attributes from the Old decl to the New one.
static void MergeAttributes(Decl *New, Decl *Old) {
Attr *attr = const_cast<Attr*>(Old->getAttrs()), *tmp;
while (attr) {
tmp = attr;
attr = attr->getNext();
if (!DeclHasAttr(New, tmp)) {
New->addAttr(tmp);
} else {
tmp->setNext(0);
delete(tmp);
}
}
/// MergeFunctionDecl - We just parsed a function 'New' from
/// declarator D which has the same name and scope as a previous
/// declaration 'Old'. Figure out how to resolve this situation,
/// merging decls or emitting diagnostics as appropriate.
/// Redeclaration will be set true if thisNew is a redeclaration OldD.
FunctionDecl *
Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
Redeclaration = false;
// Verify the old decl was also a function.
FunctionDecl *Old = dyn_cast<FunctionDecl>(OldD);
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind,
New->getName());
Diag(OldD->getLocation(), diag::err_previous_definition);
return New;
}
QualType OldQType = Context.getCanonicalType(Old->getType());
QualType NewQType = Context.getCanonicalType(New->getType());
// C++ [dcl.fct]p3:
// All declarations for a function shall agree exactly in both the
// return type and the parameter-type-list.
if (getLangOptions().CPlusPlus && OldQType == NewQType) {
MergeAttributes(New, Old);
Redeclaration = true;
return MergeCXXFunctionDecl(New, Old);
// C: Function types need to be compatible, not identical. This handles
// duplicate function decls like "void f(int); void f(enum X);" properly.
if (!getLangOptions().CPlusPlus &&
Context.typesAreCompatible(OldQType, NewQType)) {
MergeAttributes(New, Old);
Redeclaration = true;
// A function that has already been declared has been redeclared or defined
// with a different type- show appropriate diagnostic
diag::kind PrevDiag;
if (Old->isThisDeclarationADefinition())
PrevDiag = diag::err_previous_definition;
else if (Old->isImplicit())
PrevDiag = diag::err_previous_implicit_declaration;
PrevDiag = diag::err_previous_declaration;
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
// TODO: This is totally simplistic. It should handle merging functions
// together etc, merging extern int X; int X; ...
Diag(New->getLocation(), diag::err_conflicting_types, New->getName());
Diag(Old->getLocation(), PrevDiag);
return New;
}
/// Predicate for C "tentative" external object definitions (C99 6.9.2).
Steve Naroff
committed
static bool isTentativeDefinition(VarDecl *VD) {
if (VD->isFileVarDecl())
return (!VD->getInit() &&
(VD->getStorageClass() == VarDecl::None ||
VD->getStorageClass() == VarDecl::Static));
return false;
}
/// CheckForFileScopedRedefinitions - Make sure we forgo redefinition errors
/// when dealing with C "tentative" external object definitions (C99 6.9.2).
void Sema::CheckForFileScopedRedefinitions(Scope *S, VarDecl *VD) {
bool VDIsTentative = isTentativeDefinition(VD);
bool VDIsIncompleteArray = VD->getType()->isIncompleteArrayType();
for (IdentifierResolver::iterator
I = IdResolver.begin(VD->getIdentifier(),
VD->getDeclContext(), false/*LookInParentCtx*/),
E = IdResolver.end(); I != E; ++I) {
if (*I != VD && isDeclInScope(*I, VD->getDeclContext(), S)) {
VarDecl *OldDecl = dyn_cast<VarDecl>(*I);
// Handle the following case:
// int a[10];
// int a[]; - the code below makes sure we set the correct type.
// int a[11]; - this is an error, size isn't 10.
if (OldDecl && VDIsTentative && VDIsIncompleteArray &&
OldDecl->getType()->isConstantArrayType())
VD->setType(OldDecl->getType());
// Check for "tentative" definitions. We can't accomplish this in
// MergeVarDecl since the initializer hasn't been attached.
if (!OldDecl || isTentativeDefinition(OldDecl) || VDIsTentative)
continue;
// Handle __private_extern__ just like extern.
if (OldDecl->getStorageClass() != VarDecl::Extern &&
OldDecl->getStorageClass() != VarDecl::PrivateExtern &&
VD->getStorageClass() != VarDecl::Extern &&
VD->getStorageClass() != VarDecl::PrivateExtern) {
Diag(VD->getLocation(), diag::err_redefinition, VD->getName());
Diag(OldDecl->getLocation(), diag::err_previous_definition);
}
}
}
}
/// MergeVarDecl - We just parsed a variable 'New' which has the same name
/// and scope as a previous declaration 'Old'. Figure out how to resolve this
/// situation, merging decls or emitting diagnostics as appropriate.
///
/// Tentative definition rules (C99 6.9.2p2) are checked by
/// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative
/// definitions here, since the initializer hasn't been attached.
Steve Naroff
committed
VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
// Verify the old decl was also a variable.
VarDecl *Old = dyn_cast<VarDecl>(OldD);
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind,
New->getName());
Diag(OldD->getLocation(), diag::err_previous_definition);
return New;
}
MergeAttributes(New, Old);
QualType OldCType = Context.getCanonicalType(Old->getType());
QualType NewCType = Context.getCanonicalType(New->getType());
Steve Naroff
committed
if (OldCType != NewCType && !Context.typesAreCompatible(OldCType, NewCType)) {
Diag(New->getLocation(), diag::err_redefinition, New->getName());
Diag(Old->getLocation(), diag::err_previous_definition);
return New;
}
// C99 6.2.2p4: Check if we have a static decl followed by a non-static.
if (New->getStorageClass() == VarDecl::Static &&
(Old->getStorageClass() == VarDecl::None ||
Old->getStorageClass() == VarDecl::Extern)) {
Diag(New->getLocation(), diag::err_static_non_static, New->getName());
Diag(Old->getLocation(), diag::err_previous_definition);
return New;
}
// C99 6.2.2p4: Check if we have a non-static decl followed by a static.
if (New->getStorageClass() != VarDecl::Static &&
Old->getStorageClass() == VarDecl::Static) {
Diag(New->getLocation(), diag::err_non_static_static, New->getName());
Diag(Old->getLocation(), diag::err_previous_definition);
return New;
}
// Variables with external linkage are analyzed in FinalizeDeclaratorGroup.
if (New->getStorageClass() != VarDecl::Extern && !New->isFileVarDecl()) {
Diag(New->getLocation(), diag::err_redefinition, New->getName());
Diag(Old->getLocation(), diag::err_previous_definition);
}
return New;
}
/// CheckParmsForFunctionDef - Check that the parameters of the given
/// function are appropriate for the definition of a function. This
/// takes care of any checks that cannot be performed on the
/// declaration itself, e.g., that the types of each of the function
/// parameters are complete.
bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
bool HasInvalidParm = false;
for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) {
ParmVarDecl *Param = FD->getParamDecl(p);
// C99 6.7.5.3p4: the parameters in a parameter type list in a
// function declarator that is part of a function definition of
// that function shall not have incomplete type.
if (Param->getType()->isIncompleteType() &&
!Param->isInvalidDecl()) {
Diag(Param->getLocation(), diag::err_typecheck_decl_incomplete_type,
Param->getType().getAsString());
Param->setInvalidDecl();
HasInvalidParm = true;
}
}
return HasInvalidParm;
}
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
// TODO: emit error on 'int;' or 'const enum foo;'.
// TODO: emit error on 'typedef int;'
// if (!DS.isMissingDeclaratorOk()) Diag(...);
// Get the type before calling CheckSingleAssignmentConstraints(), since
// it can promote the expression.
QualType InitType = Init->getType();
AssignConvertType ConvTy = CheckSingleAssignmentConstraints(DeclType, Init);
return DiagnoseAssignmentResult(ConvTy, Init->getLocStart(), DeclType,
InitType, Init, "initializing");
bool Sema::CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT) {
const ArrayType *AT = Context.getAsArrayType(DeclT);
if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
// C99 6.7.8p14. We have an array of character type with unknown size
// being initialized to a string literal.
llvm::APSInt ConstVal(32);
ConstVal = strLiteral->getByteLength() + 1;
// Return a new array type (C99 6.7.8p22).
DeclT = Context.getConstantArrayType(IAT->getElementType(), ConstVal,
} else {
const ConstantArrayType *CAT = cast<ConstantArrayType>(AT);
// FIXME: Avoid truncation for 64-bit length strings.
if (strLiteral->getByteLength() > (unsigned)CAT->getSize().getZExtValue())
Diag(strLiteral->getSourceRange().getBegin(),
diag::warn_initializer_string_for_char_array_too_long,
strLiteral->getSourceRange());
}
// Set type from "char *" to "constant array of char".
strLiteral->setType(DeclT);
// For now, we always return false (meaning success).
return false;
}
StringLiteral *Sema::IsStringLiteralInit(Expr *Init, QualType DeclType) {
if (AT && AT->getElementType()->isCharType()) {
return dyn_cast<StringLiteral>(Init);
}
// C99 6.7.8p3: The type of the entity to be initialized shall be an array
// of unknown size ("[]") or an object type that is not a variable array type.
if (const VariableArrayType *VAT = Context.getAsVariableArrayType(DeclType))
return Diag(VAT->getSizeExpr()->getLocStart(),
diag::err_variable_object_no_init,
VAT->getSizeExpr()->getSourceRange());
// FIXME: Handle wide strings
if (StringLiteral *strLiteral = IsStringLiteralInit(Init, DeclType))
return CheckStringLiteralInit(strLiteral, DeclType);
if (DeclType->isArrayType())
return Diag(Init->getLocStart(),
diag::err_array_init_list_required,
Init->getSourceRange());
InitListChecker CheckInitList(this, InitList, DeclType);
return CheckInitList.HadError();
Chris Lattner
committed
Sema::DeclTy *
Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
ScopedDecl *LastDeclarator = dyn_cast_or_null<ScopedDecl>((Decl *)lastDecl);
Chris Lattner
committed
IdentifierInfo *II = D.getIdentifier();
// All of these full declarators require an identifier. If it doesn't have
// one, the ParsedFreeStandingDeclSpec action should be used.
if (II == 0) {
Diag(D.getDeclSpec().getSourceRange().getBegin(),
D.getDeclSpec().getSourceRange(), D.getSourceRange());
return 0;
}
// The scope passed in may not be a decl scope. Zip up the scope tree until
// we find one that is.
while ((S->getFlags() & Scope::DeclScope) == 0)
S = S->getParent();
// See if this is a redefinition of a variable in the same scope.
Douglas Gregor
committed
// In C++, the previous declaration we find might be a tag type
// (class or enum). In this case, the new declaration will hide the
// tag type.
if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
PrevDecl = 0;
QualType R = GetTypeForDeclarator(D, S);
assert(!R.isNull() && "GetTypeForDeclarator() returned null type");
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
Douglas Gregor
committed
// Check that there are no default arguments (C++ only).
if (getLangOptions().CPlusPlus)
CheckExtraCXXDefaultArguments(D);
TypedefDecl *NewTD = ParseTypedefDecl(S, D, R, LastDeclarator);
if (!NewTD) return 0;
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(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, CurContext, S)) {
NewTD = MergeTypeDefDecl(NewTD, PrevDecl);
if (NewTD == 0) return 0;
}
New = NewTD;
if (S->getFnParent() == 0) {
// C99 6.7.7p2: If a typedef name specifies a variably modified type
// then it shall have block scope.
if (NewTD->getUnderlyingType()->isVariablyModifiedType()) {
// FIXME: Diagnostic needs to be fixed.
Diag(D.getIdentifierLoc(), diag::err_typecheck_illegal_vla);
} else if (R.getTypePtr()->isFunctionType()) {
FunctionDecl::StorageClass SC = FunctionDecl::None;
switch (D.getDeclSpec().getStorageClassSpec()) {
default: assert(0 && "Unknown storage class!");
case DeclSpec::SCS_auto:
case DeclSpec::SCS_register:
Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_func,
R.getAsString());
case DeclSpec::SCS_unspecified: SC = FunctionDecl::None; break;
case DeclSpec::SCS_extern: SC = FunctionDecl::Extern; break;
case DeclSpec::SCS_static: SC = FunctionDecl::Static; break;
case DeclSpec::SCS_private_extern: SC = FunctionDecl::PrivateExtern;break;
bool isInline = D.getDeclSpec().isInlineSpecified();
FunctionDecl *NewFD;
if (D.getContext() == Declarator::MemberContext) {
// This is a C++ method declaration.
NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(CurContext),
D.getIdentifierLoc(), II, R,
(SC == FunctionDecl::Static), isInline,
LastDeclarator);
} else {
NewFD = FunctionDecl::Create(Context, CurContext,
D.getIdentifierLoc(),
II, R, SC, isInline,
LastDeclarator);
}
ProcessDeclAttributes(NewFD, 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);
NewFD->addAttr(new AsmLabelAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
// Copy the parameter declarations from the declarator D to
// the function declaration NewFD, if they are available.
if (D.getNumTypeObjects() > 0) {
DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
// Create Decl objects for each parameter, adding them to the
// FunctionDecl.
llvm::SmallVector<ParmVarDecl*, 16> Params;
// Check for C99 6.7.5.3p10 - foo(void) is a non-varargs
// function that takes no arguments, not a function that takes a
// single void argument.
// We let through "const void" here because Sema::GetTypeForDeclarator
// already checks for that case.
if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
FTI.ArgInfo[0].Param &&
((ParmVarDecl*)FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
// empty arg list, don't push any params.
ParmVarDecl *Param = (ParmVarDecl*)FTI.ArgInfo[0].Param;
// In C++, the empty parameter-type-list must be spelled "void"; a
// typedef of void is not permitted.
if (getLangOptions().CPlusPlus &&
Param->getType().getUnqualifiedType() != Context.VoidTy) {
Diag(Param->getLocation(), diag::ext_param_typedef_of_void);
}
} else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
Params.push_back((ParmVarDecl *)FTI.ArgInfo[i].Param);
}
NewFD->setParams(&Params[0], Params.size());
}
// Merge the decl with the existing one if appropriate. Since C functions
// are in a flat namespace, make sure we consider decls in outer scopes.
(!getLangOptions().CPlusPlus||isDeclInScope(PrevDecl, CurContext, S))) {
bool Redeclaration = false;
NewFD = MergeFunctionDecl(NewFD, PrevDecl, Redeclaration);
if (NewFD == 0) return 0;
NewFD->setPreviousDeclaration(cast<FunctionDecl>(PrevDecl));
}
New = NewFD;
// In C++, check default arguments now that we have merged decls.
if (getLangOptions().CPlusPlus)
CheckCXXDefaultArguments(NewFD);
Douglas Gregor
committed
// Check that there are no default arguments (C++ only).
if (getLangOptions().CPlusPlus)
CheckExtraCXXDefaultArguments(D);
if (R.getTypePtr()->isObjCInterfaceType()) {
Fariborz Jahanian
committed
Diag(D.getIdentifierLoc(), diag::err_statically_allocated_object,
D.getIdentifier()->getName());
InvalidDecl = true;
}
default: assert(0 && "Unknown storage class!");
case DeclSpec::SCS_unspecified: SC = VarDecl::None; break;
case DeclSpec::SCS_extern: SC = VarDecl::Extern; break;
case DeclSpec::SCS_static: SC = VarDecl::Static; break;
case DeclSpec::SCS_auto: SC = VarDecl::Auto; break;
case DeclSpec::SCS_register: SC = VarDecl::Register; break;
case DeclSpec::SCS_private_extern: SC = VarDecl::PrivateExtern; break;
if (D.getContext() == Declarator::MemberContext) {
assert(SC == VarDecl::Static && "Invalid storage class for member!");
// This is a static data member for a C++ class.
NewVD = CXXClassVarDecl::Create(Context, cast<CXXRecordDecl>(CurContext),
D.getIdentifierLoc(), II,
R, LastDeclarator);
bool ThreadSpecified = D.getDeclSpec().isThreadSpecified();
if (S->getFnParent() == 0) {
// C99 6.9p2: The storage-class specifiers auto and register shall not
// appear in the declaration specifiers in an external declaration.
if (SC == VarDecl::Auto || SC == VarDecl::Register) {
Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope,
R.getAsString());
InvalidDecl = true;
}
}
NewVD = VarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
II, R, SC, LastDeclarator);
NewVD->setThreadSpecified(ThreadSpecified);
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(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 AsmLabelAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
// Emit an error if an address space was applied to decl with local storage.
// This includes arrays of objects with address space qualifiers, but not
// automatic variables that point to other address spaces.
// ISO/IEC TR 18037 S5.1.2
Nate Begeman
committed
if (NewVD->hasLocalStorage() && (NewVD->getType().getAddressSpace() != 0)) {
Diag(D.getIdentifierLoc(), diag::err_as_qualified_auto_decl);
InvalidDecl = true;
// 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, CurContext, S)) {
NewVD = MergeVarDecl(NewVD, PrevDecl);
if (NewVD == 0) return 0;
}
New = NewVD;
Chris Lattner
committed
// If this has an identifier, add it to the scope stack.
Argyrios Kyrtzidis
committed
if (II)
PushOnScopeChains(New, S);
// If any semantic error occurred, mark the decl as invalid.
if (D.getInvalidType() || InvalidDecl)
New->setInvalidDecl();
Chris Lattner
committed
return New;
}
bool Sema::CheckAddressConstantExpressionLValue(const Expr* Init) {
switch (Init->getStmtClass()) {
default:
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
case Expr::ParenExprClass: {
const ParenExpr* PE = cast<ParenExpr>(Init);
return CheckAddressConstantExpressionLValue(PE->getSubExpr());
case Expr::CompoundLiteralExprClass:
return cast<CompoundLiteralExpr>(Init)->isFileScope();
case Expr::DeclRefExprClass: {
const Decl *D = cast<DeclRefExpr>(Init)->getDecl();
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (VD->hasGlobalStorage())
return false;
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
return true;
}
if (isa<FunctionDecl>(D))
return false;
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
return true;
}
case Expr::MemberExprClass: {
const MemberExpr *M = cast<MemberExpr>(Init);
if (M->isArrow())
return CheckAddressConstantExpression(M->getBase());
return CheckAddressConstantExpressionLValue(M->getBase());
}
case Expr::ArraySubscriptExprClass: {
// FIXME: Should we pedwarn for "x[0+0]" (where x is a pointer)?
const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(Init);
return CheckAddressConstantExpression(ASE->getBase()) ||
CheckArithmeticConstantExpression(ASE->getIdx());
}
case Expr::StringLiteralClass:
return false;
case Expr::UnaryOperatorClass: {
const UnaryOperator *Exp = cast<UnaryOperator>(Init);
// C99 6.6p9
if (Exp->getOpcode() == UnaryOperator::Deref)
return CheckAddressConstantExpression(Exp->getSubExpr());
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
return true;
}
}
}
bool Sema::CheckAddressConstantExpression(const Expr* Init) {
switch (Init->getStmtClass()) {
default:
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
return true;
case Expr::ParenExprClass: {
const ParenExpr* PE = cast<ParenExpr>(Init);
return CheckAddressConstantExpression(PE->getSubExpr());
}
case Expr::StringLiteralClass:
case Expr::ObjCStringLiteralClass:
return false;
case Expr::CallExprClass: {
const CallExpr *CE = cast<CallExpr>(Init);
if (CE->isBuiltinConstantExpr())
return false;
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
return true;
}
case Expr::UnaryOperatorClass: {
const UnaryOperator *Exp = cast<UnaryOperator>(Init);
// C99 6.6p9
if (Exp->getOpcode() == UnaryOperator::AddrOf)
return CheckAddressConstantExpressionLValue(Exp->getSubExpr());
if (Exp->getOpcode() == UnaryOperator::Extension)
return CheckAddressConstantExpression(Exp->getSubExpr());
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
return true;
}
case Expr::BinaryOperatorClass: {
// FIXME: Should we pedwarn for expressions like "a + 1 + 2"?
const BinaryOperator *Exp = cast<BinaryOperator>(Init);
Expr *PExp = Exp->getLHS();
Expr *IExp = Exp->getRHS();
if (IExp->getType()->isPointerType())
std::swap(PExp, IExp);
// FIXME: Should we pedwarn if IExp isn't an integer constant expression?
return CheckAddressConstantExpression(PExp) ||
CheckArithmeticConstantExpression(IExp);
}
case Expr::ImplicitCastExprClass:
case Expr::ExplicitCastExprClass: {
const Expr* SubExpr = cast<CastExpr>(Init)->getSubExpr();
if (Init->getStmtClass() == Expr::ImplicitCastExprClass) {
// Check for implicit promotion
if (SubExpr->getType()->isFunctionType() ||
SubExpr->getType()->isArrayType())
return CheckAddressConstantExpressionLValue(SubExpr);
}
// Check for pointer->pointer cast
if (SubExpr->getType()->isPointerType())
return CheckAddressConstantExpression(SubExpr);
if (SubExpr->getType()->isIntegralType()) {
// Check for the special-case of a pointer->int->pointer cast;
// this isn't standard, but some code requires it. See
// PR2720 for an example.
if (const CastExpr* SubCast = dyn_cast<CastExpr>(SubExpr)) {
if (SubCast->getSubExpr()->getType()->isPointerType()) {
unsigned IntWidth = Context.getIntWidth(SubCast->getType());
unsigned PointerWidth = Context.getTypeSize(Context.VoidPtrTy);
if (IntWidth >= PointerWidth) {
return CheckAddressConstantExpression(SubCast->getSubExpr());
}
}
}
}
if (SubExpr->getType()->isArithmeticType()) {
return CheckArithmeticConstantExpression(SubExpr);
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
return true;
}
case Expr::ConditionalOperatorClass: {
// FIXME: Should we pedwarn here?
const ConditionalOperator *Exp = cast<ConditionalOperator>(Init);
if (!Exp->getCond()->getType()->isArithmeticType()) {
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
return true;
}
if (CheckArithmeticConstantExpression(Exp->getCond()))
return true;
if (Exp->getLHS() &&
CheckAddressConstantExpression(Exp->getLHS()))
return true;
return CheckAddressConstantExpression(Exp->getRHS());
}
case Expr::AddrLabelExprClass:
return false;
}
}
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
static const Expr* FindExpressionBaseAddress(const Expr* E);
static const Expr* FindExpressionBaseAddressLValue(const Expr* E) {
switch (E->getStmtClass()) {
default:
return E;
case Expr::ParenExprClass: {
const ParenExpr* PE = cast<ParenExpr>(E);
return FindExpressionBaseAddressLValue(PE->getSubExpr());
}
case Expr::MemberExprClass: {
const MemberExpr *M = cast<MemberExpr>(E);
if (M->isArrow())
return FindExpressionBaseAddress(M->getBase());
return FindExpressionBaseAddressLValue(M->getBase());
}
case Expr::ArraySubscriptExprClass: {
const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(E);
return FindExpressionBaseAddress(ASE->getBase());
}
case Expr::UnaryOperatorClass: {
const UnaryOperator *Exp = cast<UnaryOperator>(E);
if (Exp->getOpcode() == UnaryOperator::Deref)
return FindExpressionBaseAddress(Exp->getSubExpr());
return E;
}
}
}