/// the definition of a tag (enumeration, class, struct, or union).
virtual void ActOnTagFinishDefinition(Scope *S, DeclTy *TagDecl);
+ EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum,
+ EnumConstantDecl *LastEnumConst,
+ SourceLocation IdLoc,
+ IdentifierInfo *Id,
+ ExprArg val);
+
virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl,
DeclTy *LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id,
ProcessDeclAttributeList(Record, Attr);
}
+EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
+ EnumConstantDecl *LastEnumConst,
+ SourceLocation IdLoc,
+ IdentifierInfo *Id,
+ ExprArg val) {
+ Expr *Val = (Expr *)val.get();
+
+ llvm::APSInt EnumVal(32);
+ QualType EltTy;
+ if (Val && !Val->isTypeDependent()) {
+ // Make sure to promote the operand type to int.
+ UsualUnaryConversions(Val);
+ if (Val != val.get()) {
+ val.release();
+ val = Val;
+ }
+
+ // C99 6.7.2.2p2: Make sure we have an integer constant expression.
+ SourceLocation ExpLoc;
+ if (!Val->isValueDependent() &&
+ VerifyIntegerConstantExpression(Val, &EnumVal)) {
+ Val = 0;
+ } else {
+ EltTy = Val->getType();
+ }
+ }
+
+ if (!Val) {
+ if (LastEnumConst) {
+ // Assign the last value + 1.
+ EnumVal = LastEnumConst->getInitVal();
+ ++EnumVal;
+
+ // Check for overflow on increment.
+ if (EnumVal < LastEnumConst->getInitVal())
+ Diag(IdLoc, diag::warn_enum_value_overflow);
+
+ EltTy = LastEnumConst->getType();
+ } else {
+ // First value, set to zero.
+ EltTy = Context.IntTy;
+ EnumVal.zextOrTrunc(static_cast<uint32_t>(Context.getTypeSize(EltTy)));
+ }
+ }
+
+ val.release();
+ return EnumConstantDecl::Create(Context, Enum, IdLoc, Id, EltTy,
+ Val, EnumVal);
+}
+
+
Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
DeclTy *lastEnumConst,
SourceLocation IdLoc, IdentifierInfo *Id,
}
}
- llvm::APSInt EnumVal(32);
- QualType EltTy;
- if (Val) {
- // Make sure to promote the operand type to int.
- UsualUnaryConversions(Val);
-
- // C99 6.7.2.2p2: Make sure we have an integer constant expression.
- SourceLocation ExpLoc;
- if (VerifyIntegerConstantExpression(Val, &EnumVal)) {
- Val->Destroy(Context);
- Val = 0; // Just forget about it.
- } else {
- EltTy = Val->getType();
- }
- }
-
- if (!Val) {
- if (LastEnumConst) {
- // Assign the last value + 1.
- EnumVal = LastEnumConst->getInitVal();
- ++EnumVal;
+ EnumConstantDecl *New = CheckEnumConstant(TheEnumDecl, LastEnumConst,
+ IdLoc, Id, Owned(Val));
- // Check for overflow on increment.
- if (EnumVal < LastEnumConst->getInitVal())
- Diag(IdLoc, diag::warn_enum_value_overflow);
-
- EltTy = LastEnumConst->getType();
- } else {
- // First value, set to zero.
- EltTy = Context.IntTy;
- EnumVal.zextOrTrunc(static_cast<uint32_t>(Context.getTypeSize(EltTy)));
- }
- }
-
- EnumConstantDecl *New =
- EnumConstantDecl::Create(Context, TheEnumDecl, IdLoc, Id, EltTy,
- Val, EnumVal);
-
// Register this decl in the current scope stack.
- PushOnScopeChains(New, S);
+ if (New)
+ PushOnScopeChains(New, S);
return New;
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitParenExpr(ParenExpr *E) {
- Sema::OwningExprResult SubExpr
- = SemaRef.InstantiateExpr(E->getSubExpr(), TemplateArgs, NumTemplateArgs);
+ Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
if (SubExpr.isInvalid())
return SemaRef.ExprError();
// expression.
First.release();
Second.release();
+ // FIXME: Don't reuse the callee here. We need to instantiate it.
return SemaRef.Owned(new (SemaRef.Context) CXXOperatorCallExpr(
SemaRef.Context,
E->getOperator(),
} else
Invalid = true;
+ } else if (EnumDecl *Enum = dyn_cast<EnumDecl>(*Member)) {
+ // FIXME: Spaghetti, anyone?
+ EnumDecl *New = EnumDecl::Create(Context, ClassTemplateSpec,
+ Enum->getLocation(),
+ Enum->getIdentifier(),
+ /*PrevDecl=*/0);
+ ClassTemplateSpec->addDecl(New);
+ New->startDefinition();
+
+ llvm::SmallVector<DeclTy *, 16> Enumerators;
+
+ EnumConstantDecl *LastEnumConst = 0;
+ for (EnumDecl::enumerator_iterator EC = Enum->enumerator_begin(),
+ ECEnd = Enum->enumerator_end();
+ EC != ECEnd; ++EC) {
+ // The specified value for the enumerator.
+ OwningExprResult Value = Owned((Expr *)0);
+ if (Expr *UninstValue = EC->getInitExpr())
+ Value = InstantiateExpr(UninstValue,
+ ClassTemplateSpec->getTemplateArgs(),
+ ClassTemplateSpec->getNumTemplateArgs());
+
+ // Drop the initial value and continue.
+ bool isInvalid = false;
+ if (Value.isInvalid()) {
+ Value = Owned((Expr *)0);
+ isInvalid = true;
+ }
+
+ EnumConstantDecl *NewEnumConst
+ = CheckEnumConstant(New, LastEnumConst,
+ EC->getLocation(),
+ EC->getIdentifier(),
+ move(Value));
+
+ if (isInvalid) {
+ if (NewEnumConst)
+ NewEnumConst->setInvalidDecl();
+ New->setInvalidDecl();
+ Invalid = true;
+ }
+
+ if (NewEnumConst) {
+ New->addDecl(NewEnumConst);
+ Enumerators.push_back(NewEnumConst);
+ LastEnumConst = NewEnumConst;
+ }
+ }
+
+ ActOnEnumBody(New->getLocation(), New,
+ &Enumerators[0], Enumerators.size());
}
}