Newer
Older
//===------ SemaDeclCXX.cpp - Semantic Analysis for C++ 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 C++ declarations.
//
//===----------------------------------------------------------------------===//
#include "Sema.h"
#include "SemaInherit.h"
Argyrios Kyrtzidis
committed
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/AST/StmtVisitor.h"
Argyrios Kyrtzidis
committed
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Parse/DeclSpec.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Compiler.h"
#include <algorithm> // for std::equal
#include <map>
using namespace clang;
//===----------------------------------------------------------------------===//
// CheckDefaultArgumentVisitor
//===----------------------------------------------------------------------===//
namespace {
/// CheckDefaultArgumentVisitor - C++ [dcl.fct.default] Traverses
/// the default argument of a parameter to determine whether it
/// contains any ill-formed subexpressions. For example, this will
/// diagnose the use of local variables or parameters within the
/// default argument expression.
class VISIBILITY_HIDDEN CheckDefaultArgumentVisitor
: public StmtVisitor<CheckDefaultArgumentVisitor, bool> {
Expr *DefaultArg;
Sema *S;
public:
CheckDefaultArgumentVisitor(Expr *defarg, Sema *s)
: DefaultArg(defarg), S(s) {}
bool VisitExpr(Expr *Node);
bool VisitDeclRefExpr(DeclRefExpr *DRE);
Douglas Gregor
committed
bool VisitCXXThisExpr(CXXThisExpr *ThisE);
};
/// VisitExpr - Visit all of the children of this expression.
bool CheckDefaultArgumentVisitor::VisitExpr(Expr *Node) {
bool IsInvalid = false;
for (Stmt::child_iterator I = Node->child_begin(),
E = Node->child_end(); I != E; ++I)
IsInvalid |= Visit(*I);
return IsInvalid;
/// VisitDeclRefExpr - Visit a reference to a declaration, to
/// determine whether this declaration can be used in the default
/// argument expression.
bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(DeclRefExpr *DRE) {
NamedDecl *Decl = DRE->getDecl();
if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(Decl)) {
// C++ [dcl.fct.default]p9
// Default arguments are evaluated each time the function is
// called. The order of evaluation of function arguments is
// unspecified. Consequently, parameters of a function shall not
// be used in default argument expressions, even if they are not
// evaluated. Parameters of a function declared before a default
// argument expression are in scope and can hide namespace and
// class member names.
return S->Diag(DRE->getSourceRange().getBegin(),
diag::err_param_default_argument_references_param,
Param->getName(), DefaultArg->getSourceRange());
} else if (VarDecl *VDecl = dyn_cast<VarDecl>(Decl)) {
// C++ [dcl.fct.default]p7
// Local variables shall not be used in default argument
// expressions.
if (VDecl->isBlockVarDecl())
return S->Diag(DRE->getSourceRange().getBegin(),
diag::err_param_default_argument_references_local,
VDecl->getName(), DefaultArg->getSourceRange());
Douglas Gregor
committed
return false;
}
Douglas Gregor
committed
/// VisitCXXThisExpr - Visit a C++ "this" expression.
bool CheckDefaultArgumentVisitor::VisitCXXThisExpr(CXXThisExpr *ThisE) {
// C++ [dcl.fct.default]p8:
// The keyword this shall not be used in a default argument of a
// member function.
return S->Diag(ThisE->getSourceRange().getBegin(),
diag::err_param_default_argument_references_this,
ThisE->getSourceRange());
}
/// ActOnParamDefaultArgument - Check whether the default argument
/// provided for a function parameter is well-formed. If so, attach it
/// to the parameter declaration.
void
Sema::ActOnParamDefaultArgument(DeclTy *param, SourceLocation EqualLoc,
ExprTy *defarg) {
ParmVarDecl *Param = (ParmVarDecl *)param;
llvm::OwningPtr<Expr> DefaultArg((Expr *)defarg);
QualType ParamType = Param->getType();
// Default arguments are only permitted in C++
if (!getLangOptions().CPlusPlus) {
Diag(EqualLoc, diag::err_param_default_argument,
DefaultArg->getSourceRange());
return;
}
// C++ [dcl.fct.default]p5
// A default argument expression is implicitly converted (clause
// 4) to the parameter type. The default argument expression has
// the same semantic constraints as the initializer expression in
// a declaration of a variable of the parameter type, using the
// copy-initialization semantics (8.5).
Expr *DefaultArgPtr = DefaultArg.get();
Douglas Gregor
committed
bool DefaultInitFailed = PerformCopyInitialization(DefaultArgPtr, ParamType,
"in default argument");
if (DefaultArgPtr != DefaultArg.get()) {
DefaultArg.take();
DefaultArg.reset(DefaultArgPtr);
}
Douglas Gregor
committed
if (DefaultInitFailed) {
return;
}
// Check that the default argument is well-formed
CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg.get(), this);
if (DefaultArgChecker.Visit(DefaultArg.get()))
return;
// Okay: add the default argument to the parameter
Param->setDefaultArg(DefaultArg.take());
}
Douglas Gregor
committed
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/// CheckExtraCXXDefaultArguments - Check for any extra default
/// arguments in the declarator, which is not a function declaration
/// or definition and therefore is not permitted to have default
/// arguments. This routine should be invoked for every declarator
/// that is not a function declaration or definition.
void Sema::CheckExtraCXXDefaultArguments(Declarator &D) {
// C++ [dcl.fct.default]p3
// A default argument expression shall be specified only in the
// parameter-declaration-clause of a function declaration or in a
// template-parameter (14.1). It shall not be specified for a
// parameter pack. If it is specified in a
// parameter-declaration-clause, it shall not occur within a
// declarator or abstract-declarator of a parameter-declaration.
for (unsigned i = 0; i < D.getNumTypeObjects(); ++i) {
DeclaratorChunk &chunk = D.getTypeObject(i);
if (chunk.Kind == DeclaratorChunk::Function) {
for (unsigned argIdx = 0; argIdx < chunk.Fun.NumArgs; ++argIdx) {
ParmVarDecl *Param = (ParmVarDecl *)chunk.Fun.ArgInfo[argIdx].Param;
if (Param->getDefaultArg()) {
Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc,
Param->getDefaultArg()->getSourceRange());
Param->setDefaultArg(0);
}
}
}
}
}
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
// MergeCXXFunctionDecl - Merge two declarations of the same C++
// function, once we already know that they have the same
// type. Subroutine of MergeFunctionDecl.
FunctionDecl *
Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
// C++ [dcl.fct.default]p4:
//
// For non-template functions, default arguments can be added in
// later declarations of a function in the same
// scope. Declarations in different scopes have completely
// distinct sets of default arguments. That is, declarations in
// inner scopes do not acquire default arguments from
// declarations in outer scopes, and vice versa. In a given
// function declaration, all parameters subsequent to a
// parameter with a default argument shall have default
// arguments supplied in this or previous declarations. A
// default argument shall not be redefined by a later
// declaration (not even to the same value).
for (unsigned p = 0, NumParams = Old->getNumParams(); p < NumParams; ++p) {
ParmVarDecl *OldParam = Old->getParamDecl(p);
ParmVarDecl *NewParam = New->getParamDecl(p);
if(OldParam->getDefaultArg() && NewParam->getDefaultArg()) {
Diag(NewParam->getLocation(),
diag::err_param_default_argument_redefinition,
NewParam->getDefaultArg()->getSourceRange());
Diag(OldParam->getLocation(), diag::err_previous_definition);
} else if (OldParam->getDefaultArg()) {
// Merge the old default argument into the new parameter
NewParam->setDefaultArg(OldParam->getDefaultArg());
}
}
return New;
}
/// CheckCXXDefaultArguments - Verify that the default arguments for a
/// function declaration are well-formed according to C++
/// [dcl.fct.default].
void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
unsigned NumParams = FD->getNumParams();
unsigned p;
// Find first parameter with a default argument
for (p = 0; p < NumParams; ++p) {
ParmVarDecl *Param = FD->getParamDecl(p);
if (Param->getDefaultArg())
break;
}
// C++ [dcl.fct.default]p4:
// In a given function declaration, all parameters
// subsequent to a parameter with a default argument shall
// have default arguments supplied in this or previous
// declarations. A default argument shall not be redefined
// by a later declaration (not even to the same value).
unsigned LastMissingDefaultArg = 0;
for(; p < NumParams; ++p) {
ParmVarDecl *Param = FD->getParamDecl(p);
if (!Param->getDefaultArg()) {
if (Param->getIdentifier())
Diag(Param->getLocation(),
diag::err_param_default_argument_missing_name,
Param->getIdentifier()->getName());
else
Diag(Param->getLocation(),
diag::err_param_default_argument_missing);
LastMissingDefaultArg = p;
}
}
if (LastMissingDefaultArg > 0) {
// Some default arguments were missing. Clear out all of the
// default arguments up to (and including) the last missing
// default argument, so that we leave the function parameters
// in a semantically valid state.
for (p = 0; p <= LastMissingDefaultArg; ++p) {
ParmVarDecl *Param = FD->getParamDecl(p);
if (Param->getDefaultArg()) {
delete Param->getDefaultArg();
Param->setDefaultArg(0);
}
}
}
}
/// isCurrentClassName - Determine whether the identifier II is the
/// name of the class type currently being defined. In the case of
/// nested classes, this will only return true if II is the name of
/// the innermost class.
Argyrios Kyrtzidis
committed
bool Sema::isCurrentClassName(const IdentifierInfo &II, Scope *,
const CXXScopeSpec *SS) {
CXXRecordDecl *CurDecl;
if (SS) {
DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep());
CurDecl = dyn_cast_or_null<CXXRecordDecl>(DC);
} else
CurDecl = dyn_cast_or_null<CXXRecordDecl>(CurContext);
if (CurDecl)
return &II == CurDecl->getIdentifier();
else
return false;
}
/// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is
/// one entry in the base class list of a class specifier, for
/// example:
/// class foo : public bar, virtual private baz {
/// 'public bar' and 'virtual private baz' are each base-specifiers.
Sema::BaseResult
Sema::ActOnBaseSpecifier(DeclTy *classdecl, SourceRange SpecifierRange,
bool Virtual, AccessSpecifier Access,
TypeTy *basetype, SourceLocation BaseLoc) {
RecordDecl *Decl = (RecordDecl*)classdecl;
QualType BaseType = Context.getTypeDeclType((TypeDecl*)basetype);
// Base specifiers must be record types.
if (!BaseType->isRecordType()) {
Diag(BaseLoc, diag::err_base_must_be_class, SpecifierRange);
return true;
}
// C++ [class.union]p1:
// A union shall not be used as a base class.
if (BaseType->isUnionType()) {
Diag(BaseLoc, diag::err_union_as_base_class, SpecifierRange);
return true;
}
// C++ [class.union]p1:
// A union shall not have base classes.
Diag(Decl->getLocation(), diag::err_base_clause_on_union,
SpecifierRange);
return true;
}
// C++ [class.derived]p2:
// The class-name in a base-specifier shall not be an incompletely
// defined class.
if (BaseType->isIncompleteType()) {
Diag(BaseLoc, diag::err_incomplete_base_class, SpecifierRange);
return true;
}
// If the base class is polymorphic, the new one is, too.
RecordDecl *BaseDecl = BaseType->getAsRecordType()->getDecl();
assert(BaseDecl && "Record type has no declaration");
BaseDecl = BaseDecl->getDefinition(Context);
assert(BaseDecl && "Base type is not incomplete, but has no definition");
if (cast<CXXRecordDecl>(BaseDecl)->isPolymorphic()) {
cast<CXXRecordDecl>(Decl)->setPolymorphic(true);
}
// Create the base specifier.
return new CXXBaseSpecifier(SpecifierRange, Virtual,
BaseType->isClassType(), Access, BaseType);
}
/// ActOnBaseSpecifiers - Attach the given base specifiers to the
/// class, after checking whether there are any duplicate base
/// classes.
void Sema::ActOnBaseSpecifiers(DeclTy *ClassDecl, BaseTy **Bases,
unsigned NumBases) {
if (NumBases == 0)
return;
// Used to keep track of which base types we have already seen, so
// that we can properly diagnose redundant direct base types. Note
// that the key is always the unqualified canonical type of the base
// class.
std::map<QualType, CXXBaseSpecifier*, QualTypeOrdering> KnownBaseTypes;
// Copy non-redundant base specifiers into permanent storage.
CXXBaseSpecifier **BaseSpecs = (CXXBaseSpecifier **)Bases;
unsigned NumGoodBases = 0;
for (unsigned idx = 0; idx < NumBases; ++idx) {
QualType NewBaseType
= Context.getCanonicalType(BaseSpecs[idx]->getType());
NewBaseType = NewBaseType.getUnqualifiedType();
if (KnownBaseTypes[NewBaseType]) {
// C++ [class.mi]p3:
// A class shall not be specified as a direct base class of a
// derived class more than once.
Diag(BaseSpecs[idx]->getSourceRange().getBegin(),
diag::err_duplicate_base_class,
KnownBaseTypes[NewBaseType]->getType().getAsString(),
BaseSpecs[idx]->getSourceRange());
// Delete the duplicate base class specifier; we're going to
// overwrite its pointer later.
delete BaseSpecs[idx];
} else {
// Okay, add this new base class.
KnownBaseTypes[NewBaseType] = BaseSpecs[idx];
BaseSpecs[NumGoodBases++] = BaseSpecs[idx];
}
}
// Attach the remaining base class specifiers to the derived class.
CXXRecordDecl *Decl = (CXXRecordDecl*)ClassDecl;
Decl->setBases(BaseSpecs, NumGoodBases);
// Delete the remaining (good) base class specifiers, since their
// data has been copied into the CXXRecordDecl.
for (unsigned idx = 0; idx < NumGoodBases; ++idx)
delete BaseSpecs[idx];
}
//===----------------------------------------------------------------------===//
// C++ class member Handling
//===----------------------------------------------------------------------===//
/// ActOnStartCXXClassDef - This is called at the start of a class/struct/union
/// definition, when on C++.
void Sema::ActOnStartCXXClassDef(Scope *S, DeclTy *D, SourceLocation LBrace) {
CXXRecordDecl *Dcl = cast<CXXRecordDecl>(static_cast<Decl *>(D));
PushDeclContext(Dcl);
if (Dcl->getIdentifier()) {
// C++ [class]p2:
// [...] The class-name is also inserted into the scope of the
// class itself; this is known as the injected-class-name. For
// purposes of access checking, the injected-class-name is treated
// as if it were a public member name.
PushOnScopeChains(Dcl, S);
}
}
/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
/// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
/// bitfield width if there is one and 'InitExpr' specifies the initializer if
/// any. 'LastInGroup' is non-null for cases where one declspec has multiple
/// declarators on it.
///
/// NOTE: Because of CXXFieldDecl's inability to be chained like ScopedDecls, if
/// an instance field is declared, a new CXXFieldDecl is created but the method
/// does *not* return it; it returns LastInGroup instead. The other C++ members
/// (which are all ScopedDecls) are returned after appending them to
/// LastInGroup.
Sema::DeclTy *
Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
ExprTy *BW, ExprTy *InitExpr,
DeclTy *LastInGroup) {
const DeclSpec &DS = D.getDeclSpec();
IdentifierInfo *II = D.getIdentifier();
Expr *BitWidth = static_cast<Expr*>(BW);
Expr *Init = static_cast<Expr*>(InitExpr);
SourceLocation Loc = D.getIdentifierLoc();
bool isFunc = D.isFunctionDeclarator();
// C++ 9.2p6: A member shall not be declared to have automatic storage
// duration (auto, register) or with the extern storage-class-specifier.
// C++ 7.1.1p8: The mutable specifier can be applied only to names of class
// data members and cannot be applied to names declared const or static,
// and cannot be applied to reference members.
switch (DS.getStorageClassSpec()) {
case DeclSpec::SCS_unspecified:
case DeclSpec::SCS_typedef:
case DeclSpec::SCS_static:
// FALL THROUGH.
break;
case DeclSpec::SCS_mutable:
if (isFunc) {
if (DS.getStorageClassSpecLoc().isValid())
Diag(DS.getStorageClassSpecLoc(),
diag::err_mutable_function);
else
Diag(DS.getThreadSpecLoc(),
diag::err_mutable_function);
D.getMutableDeclSpec().ClearStorageClassSpecs();
} else {
QualType T = GetTypeForDeclarator(D, S);
diag::kind err = static_cast<diag::kind>(0);
if (T->isReferenceType())
err = diag::err_mutable_reference;
else if (T.isConstQualified())
err = diag::err_mutable_const;
if (err != 0) {
if (DS.getStorageClassSpecLoc().isValid())
Diag(DS.getStorageClassSpecLoc(), err);
else
Diag(DS.getThreadSpecLoc(), err);
D.getMutableDeclSpec().ClearStorageClassSpecs();
}
}
break;
default:
if (DS.getStorageClassSpecLoc().isValid())
Diag(DS.getStorageClassSpecLoc(),
diag::err_storageclass_invalid_for_member);
else
Diag(DS.getThreadSpecLoc(), diag::err_storageclass_invalid_for_member);
D.getMutableDeclSpec().ClearStorageClassSpecs();
}
if (!isFunc &&
D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typedef &&
D.getNumTypeObjects() == 0) {
// Check also for this case:
//
// typedef int f();
// f a;
//
Decl *TD = static_cast<Decl *>(DS.getTypeRep());
isFunc = Context.getTypeDeclType(cast<TypeDecl>(TD))->isFunctionType();
}
bool isInstField = ((DS.getStorageClassSpec() == DeclSpec::SCS_unspecified ||
DS.getStorageClassSpec() == DeclSpec::SCS_mutable) &&
Decl *Member;
bool InvalidDecl = false;
if (isInstField)
Member = static_cast<Decl*>(ActOnField(S, Loc, D, BitWidth));
else
Member = static_cast<Decl*>(ActOnDeclarator(S, D, LastInGroup));
if (!Member) return LastInGroup;
Sanjiv Gupta
committed
assert((II || isInstField) && "No identifier for non-field ?");
// set/getAccess is not part of Decl's interface to avoid bloating it with C++
// specific methods. Use a wrapper class that can be used with all C++ class
// member decls.
CXXClassMemberWrapper(Member).setAccess(AS);
Douglas Gregor
committed
// C++ [dcl.init.aggr]p1:
// An aggregate is an array or a class (clause 9) with [...] no
// private or protected non-static data members (clause 11).
if (isInstField && (AS == AS_private || AS == AS_protected))
cast<CXXRecordDecl>(CurContext)->setAggregate(false);
if (DS.isVirtualSpecified()) {
if (!isFunc || DS.getStorageClassSpec() == DeclSpec::SCS_static) {
Diag(DS.getVirtualSpecLoc(), diag::err_virtual_non_function);
InvalidDecl = true;
} else {
CXXRecordDecl *CurClass = cast<CXXRecordDecl>(CurContext);
CurClass->setAggregate(false);
CurClass->setPolymorphic(true);
}
}
Douglas Gregor
committed
if (BitWidth) {
// C++ 9.6p2: Only when declaring an unnamed bit-field may the
// constant-expression be a value equal to zero.
// FIXME: Check this.
if (D.isFunctionDeclarator()) {
// FIXME: Emit diagnostic about only constructors taking base initializers
// or something similar, when constructor support is in place.
Diag(Loc, diag::err_not_bitfield_type,
II->getName(), BitWidth->getSourceRange());
InvalidDecl = true;
} else if (isInstField) {
// C++ 9.6p3: A bit-field shall have integral or enumeration type.
if (!cast<FieldDecl>(Member)->getType()->isIntegralType()) {
Diag(Loc, diag::err_not_integral_type_bitfield,
II->getName(), BitWidth->getSourceRange());
InvalidDecl = true;
}
} else if (isa<FunctionDecl>(Member)) {
// A function typedef ("typedef int f(); f a;").
// C++ 9.6p3: A bit-field shall have integral or enumeration type.
Diag(Loc, diag::err_not_integral_type_bitfield,
II->getName(), BitWidth->getSourceRange());
InvalidDecl = true;
} else if (isa<TypedefDecl>(Member)) {
// "cannot declare 'A' to be a bit-field type"
Diag(Loc, diag::err_not_bitfield_type, II->getName(),
BitWidth->getSourceRange());
InvalidDecl = true;
} else {
assert(isa<CXXClassVarDecl>(Member) &&
"Didn't we cover all member kinds?");
// C++ 9.6p3: A bit-field shall not be a static member.
// "static member 'A' cannot be a bit-field"
Diag(Loc, diag::err_static_not_bitfield, II->getName(),
BitWidth->getSourceRange());
InvalidDecl = true;
}
}
if (Init) {
// C++ 9.2p4: A member-declarator can contain a constant-initializer only
// if it declares a static member of const integral or const enumeration
// type.
if (CXXClassVarDecl *CVD = dyn_cast<CXXClassVarDecl>(Member)) {
// ...static member of...
CVD->setInit(Init);
// ...const integral or const enumeration type.
if (Context.getCanonicalType(CVD->getType()).isConstQualified() &&
CVD->getType()->isIntegralType()) {
// constant-initializer
if (CheckForConstantInitializer(Init, CVD->getType()))
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
InvalidDecl = true;
} else {
// not const integral.
Diag(Loc, diag::err_member_initialization,
II->getName(), Init->getSourceRange());
InvalidDecl = true;
}
} else {
// not static member.
Diag(Loc, diag::err_member_initialization,
II->getName(), Init->getSourceRange());
InvalidDecl = true;
}
}
if (InvalidDecl)
Member->setInvalidDecl();
if (isInstField) {
FieldCollector->Add(cast<CXXFieldDecl>(Member));
return LastInGroup;
}
return Member;
}
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
/// ActOnMemInitializer - Handle a C++ member initializer.
Sema::MemInitResult
Sema::ActOnMemInitializer(DeclTy *ConstructorD,
Scope *S,
IdentifierInfo *MemberOrBase,
SourceLocation IdLoc,
SourceLocation LParenLoc,
ExprTy **Args, unsigned NumArgs,
SourceLocation *CommaLocs,
SourceLocation RParenLoc) {
CXXConstructorDecl *Constructor
= dyn_cast<CXXConstructorDecl>((Decl*)ConstructorD);
if (!Constructor) {
// The user wrote a constructor initializer on a function that is
// not a C++ constructor. Ignore the error for now, because we may
// have more member initializers coming; we'll diagnose it just
// once in ActOnMemInitializers.
return true;
}
CXXRecordDecl *ClassDecl = Constructor->getParent();
// C++ [class.base.init]p2:
// Names in a mem-initializer-id are looked up in the scope of the
// constructor’s class and, if not found in that scope, are looked
// up in the scope containing the constructor’s
// definition. [Note: if the constructor’s class contains a member
// with the same name as a direct or virtual base class of the
// class, a mem-initializer-id naming the member or base class and
// 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.
CXXFieldDecl *Member = ClassDecl->getMember(MemberOrBase);
// FIXME: Handle members of an anonymous union.
if (Member) {
// FIXME: Perform direct initialization of the member.
return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs);
}
// It didn't name a member, so see if it names a class.
Argyrios Kyrtzidis
committed
TypeTy *BaseTy = isTypeName(*MemberOrBase, S, 0/*SS*/);
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
if (!BaseTy)
return Diag(IdLoc, diag::err_mem_init_not_member_or_class,
MemberOrBase->getName(), SourceRange(IdLoc, RParenLoc));
QualType BaseType = Context.getTypeDeclType((TypeDecl *)BaseTy);
if (!BaseType->isRecordType())
return Diag(IdLoc, diag::err_base_init_does_not_name_class,
BaseType.getAsString(), SourceRange(IdLoc, RParenLoc));
// C++ [class.base.init]p2:
// [...] Unless the mem-initializer-id names a nonstatic data
// member of the constructor’s class or a direct or virtual base
// of that class, the mem-initializer is ill-formed. A
// mem-initializer-list can initialize a base class using any
// name that denotes that base class type.
// First, check for a direct base class.
const CXXBaseSpecifier *DirectBaseSpec = 0;
for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
Base != ClassDecl->bases_end(); ++Base) {
if (Context.getCanonicalType(BaseType).getUnqualifiedType() ==
Context.getCanonicalType(Base->getType()).getUnqualifiedType()) {
// We found a direct base of this type. That's what we're
// initializing.
DirectBaseSpec = &*Base;
break;
}
}
// Check for a virtual base class.
// FIXME: We might be able to short-circuit this if we know in
// advance that there are no virtual bases.
const CXXBaseSpecifier *VirtualBaseSpec = 0;
if (!DirectBaseSpec || !DirectBaseSpec->isVirtual()) {
// We haven't found a base yet; search the class hierarchy for a
// virtual base class.
BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
if (IsDerivedFrom(Context.getTypeDeclType(ClassDecl), BaseType, Paths)) {
for (BasePaths::paths_iterator Path = Paths.begin();
Path != Paths.end(); ++Path) {
if (Path->back().Base->isVirtual()) {
VirtualBaseSpec = Path->back().Base;
break;
}
}
}
}
// C++ [base.class.init]p2:
// If a mem-initializer-id is ambiguous because it designates both
// a direct non-virtual base class and an inherited virtual base
// class, the mem-initializer is ill-formed.
if (DirectBaseSpec && VirtualBaseSpec)
return Diag(IdLoc, diag::err_base_init_direct_and_virtual,
MemberOrBase->getName(), SourceRange(IdLoc, RParenLoc));
return new CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs);
}
void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
DeclTy *TagDecl,
SourceLocation LBrac,
SourceLocation RBrac) {
ActOnFields(S, RLoc, TagDecl,
(DeclTy**)FieldCollector->getCurFields(),
FieldCollector->getCurNumFields(), LBrac, RBrac, 0);
/// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared
/// special functions, such as the default constructor, copy
/// constructor, or destructor, to the given C++ class (C++
/// [special]p1). This routine can only be executed just before the
/// definition of the class is complete.
void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
QualType ClassType = Context.getTypeDeclType(ClassDecl);
ClassType = Context.getCanonicalType(ClassType);
if (!ClassDecl->hasUserDeclaredConstructor()) {
// C++ [class.ctor]p5:
// A default constructor for a class X is a constructor of class X
// that can be called without an argument. If there is no
// user-declared constructor for class X, a default constructor is
// implicitly declared. An implicitly-declared default constructor
// is an inline public member of its class.
DeclarationName Name
= Context.DeclarationNames.getCXXConstructorName(ClassType);
CXXConstructorDecl *DefaultCon =
CXXConstructorDecl::Create(Context, ClassDecl,
ClassDecl->getLocation(), Name,
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
Context.getFunctionType(Context.VoidTy,
0, 0, false, 0),
/*isExplicit=*/false,
/*isInline=*/true,
/*isImplicitlyDeclared=*/true);
DefaultCon->setAccess(AS_public);
ClassDecl->addConstructor(Context, DefaultCon);
}
if (!ClassDecl->hasUserDeclaredCopyConstructor()) {
// C++ [class.copy]p4:
// If the class definition does not explicitly declare a copy
// constructor, one is declared implicitly.
// C++ [class.copy]p5:
// The implicitly-declared copy constructor for a class X will
// have the form
//
// X::X(const X&)
//
// if
bool HasConstCopyConstructor = true;
// -- each direct or virtual base class B of X has a copy
// constructor whose first parameter is of type const B& or
// const volatile B&, and
for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
HasConstCopyConstructor && Base != ClassDecl->bases_end(); ++Base) {
const CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
HasConstCopyConstructor
= BaseClassDecl->hasConstCopyConstructor(Context);
}
// -- for all the nonstatic data members of X that are of a
// 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();
HasConstCopyConstructor && Field != ClassDecl->field_end(); ++Field) {
QualType FieldType = (*Field)->getType();
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
if (const RecordType *FieldClassType = FieldType->getAsRecordType()) {
const CXXRecordDecl *FieldClassDecl
= cast<CXXRecordDecl>(FieldClassType->getDecl());
HasConstCopyConstructor
= FieldClassDecl->hasConstCopyConstructor(Context);
}
}
// Otherwise, the implicitly declared copy constructor will have
// the form
//
// X::X(X&)
QualType ArgType = Context.getTypeDeclType(ClassDecl);
if (HasConstCopyConstructor)
ArgType = ArgType.withConst();
ArgType = Context.getReferenceType(ArgType);
// An implicitly-declared copy constructor is an inline public
// member of its class.
DeclarationName Name
= Context.DeclarationNames.getCXXConstructorName(ClassType);
CXXConstructorDecl *CopyConstructor
= CXXConstructorDecl::Create(Context, ClassDecl,
ClassDecl->getLocation(), Name,
Context.getFunctionType(Context.VoidTy,
&ArgType, 1,
false, 0),
/*isExplicit=*/false,
/*isInline=*/true,
/*isImplicitlyDeclared=*/true);
CopyConstructor->setAccess(AS_public);
// Add the parameter to the constructor.
ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyConstructor,
ClassDecl->getLocation(),
/*IdentifierInfo=*/0,
ArgType, VarDecl::None, 0, 0);
CopyConstructor->setParams(&FromParam, 1);
ClassDecl->addConstructor(Context, CopyConstructor);
}
if (!ClassDecl->getDestructor()) {
// C++ [class.dtor]p2:
// If a class has no user-declared destructor, a destructor is
// declared implicitly. An implicitly-declared destructor is an
// inline public member of its class.
DeclarationName Name
= Context.DeclarationNames.getCXXDestructorName(ClassType);
CXXDestructorDecl *Destructor
= CXXDestructorDecl::Create(Context, ClassDecl,
ClassDecl->getLocation(), Name,
Context.getFunctionType(Context.VoidTy,
0, 0, false, 0),
/*isInline=*/true,
/*isImplicitlyDeclared=*/true);
Destructor->setAccess(AS_public);
ClassDecl->setDestructor(Destructor);
}
// FIXME: Implicit copy assignment operator
}
Argyrios Kyrtzidis
committed
void Sema::ActOnFinishCXXClassDef(DeclTy *D) {
Argyrios Kyrtzidis
committed
CXXRecordDecl *Rec = cast<CXXRecordDecl>(static_cast<Decl *>(D));
AddImplicitlyDeclaredMembersToClass(Rec);
Argyrios Kyrtzidis
committed
// Everything, including inline method definitions, have been parsed.
// Let the consumer know of the new TagDecl definition.
Consumer.HandleTagDeclDefinition(Rec);
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
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
/// CheckConstructorDeclarator - Called by ActOnDeclarator to check
/// the well-formednes of the constructor declarator @p D with type @p
/// R. If there are any errors in the declarator, this routine will
/// emit diagnostics and return true. Otherwise, it will return
/// false. Either way, the type @p R will be updated to reflect a
/// well-formed type for the constructor.
bool Sema::CheckConstructorDeclarator(Declarator &D, QualType &R,
FunctionDecl::StorageClass& SC) {
bool isVirtual = D.getDeclSpec().isVirtualSpecified();
bool isInvalid = false;
// C++ [class.ctor]p3:
// A constructor shall not be virtual (10.3) or static (9.4). A
// constructor can be invoked for a const, volatile or const
// volatile object. A constructor shall not be declared const,
// volatile, or const volatile (9.3.2).
if (isVirtual) {
Diag(D.getIdentifierLoc(),
diag::err_constructor_cannot_be,
"virtual",
SourceRange(D.getDeclSpec().getVirtualSpecLoc()),
SourceRange(D.getIdentifierLoc()));
isInvalid = true;
}
if (SC == FunctionDecl::Static) {
Diag(D.getIdentifierLoc(),
diag::err_constructor_cannot_be,
"static",
SourceRange(D.getDeclSpec().getStorageClassSpecLoc()),
SourceRange(D.getIdentifierLoc()));
isInvalid = true;
SC = FunctionDecl::None;
}
if (D.getDeclSpec().hasTypeSpecifier()) {
// Constructors don't have return types, but the parser will
// happily parse something like:
//
// class X {
// float X(float);
// };
//
// The return type will be eliminated later.
Diag(D.getIdentifierLoc(),
diag::err_constructor_return_type,
SourceRange(D.getDeclSpec().getTypeSpecTypeLoc()),
SourceRange(D.getIdentifierLoc()));
}
if (R->getAsFunctionTypeProto()->getTypeQuals() != 0) {
DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
if (FTI.TypeQuals & QualType::Const)
Diag(D.getIdentifierLoc(),
diag::err_invalid_qualified_constructor,
"const",
SourceRange(D.getIdentifierLoc()));
if (FTI.TypeQuals & QualType::Volatile)
Diag(D.getIdentifierLoc(),
diag::err_invalid_qualified_constructor,
"volatile",
SourceRange(D.getIdentifierLoc()));
if (FTI.TypeQuals & QualType::Restrict)
Diag(D.getIdentifierLoc(),
diag::err_invalid_qualified_constructor,
"restrict",
SourceRange(D.getIdentifierLoc()));
}
// Rebuild the function type "R" without any type qualifiers (in
// case any of the errors above fired) and with "void" as the
// return type, since constructors don't have return types. We
// *always* have to do this, because GetTypeForDeclarator will
// put in a result type of "int" when none was specified.
const FunctionTypeProto *Proto = R->getAsFunctionTypeProto();
R = Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(),
Proto->getNumArgs(),
Proto->isVariadic(),
0);
return isInvalid;
}
/// CheckDestructorDeclarator - Called by ActOnDeclarator to check
/// the well-formednes of the destructor declarator @p D with type @p
/// R. If there are any errors in the declarator, this routine will
/// emit diagnostics and return true. Otherwise, it will return
/// false. Either way, the type @p R will be updated to reflect a
/// well-formed type for the destructor.
bool Sema::CheckDestructorDeclarator(Declarator &D, QualType &R,
FunctionDecl::StorageClass& SC) {
bool isInvalid = false;
// C++ [class.dtor]p1:
// [...] A typedef-name that names a class is a class-name
// (7.1.3); however, a typedef-name that names a class shall not
// be used as the identifier in the declarator for a destructor
// declaration.
TypeDecl *DeclaratorTypeD = (TypeDecl *)D.getDeclaratorIdType();
if (const TypedefDecl *TypedefD = dyn_cast<TypedefDecl>(DeclaratorTypeD)) {
Diag(D.getIdentifierLoc(),
diag::err_destructor_typedef_name,
TypedefD->getName());
isInvalid = true;
962
963
964
965
966
967
968
969
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
}
// C++ [class.dtor]p2:
// A destructor is used to destroy objects of its class type. A
// destructor takes no parameters, and no return type can be
// specified for it (not even void). The address of a destructor
// shall not be taken. A destructor shall not be static. A
// destructor can be invoked for a const, volatile or const
// volatile object. A destructor shall not be declared const,
// volatile or const volatile (9.3.2).
if (SC == FunctionDecl::Static) {
Diag(D.getIdentifierLoc(),
diag::err_destructor_cannot_be,
"static",
SourceRange(D.getDeclSpec().getStorageClassSpecLoc()),
SourceRange(D.getIdentifierLoc()));
isInvalid = true;
SC = FunctionDecl::None;
}
if (D.getDeclSpec().hasTypeSpecifier()) {
// Destructors don't have return types, but the parser will
// happily parse something like:
//
// class X {
// float ~X();
// };
//
// The return type will be eliminated later.
Diag(D.getIdentifierLoc(),
diag::err_destructor_return_type,
SourceRange(D.getDeclSpec().getTypeSpecTypeLoc()),
SourceRange(D.getIdentifierLoc()));
}
if (R->getAsFunctionTypeProto()->getTypeQuals() != 0) {
DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
if (FTI.TypeQuals & QualType::Const)
Diag(D.getIdentifierLoc(),
diag::err_invalid_qualified_destructor,
"const",