/// \brief Represents an implicitly-generated value initialization of
/// an object of a given type.
///
-/// Implicit value initializations occur within semantic initialize
-/// list expressions (\see InitListExpr) as placeholders for subobject
+/// Implicit value initializations occur within semantic initializer
+/// list expressions (InitListExpr) as placeholders for subobject
/// initializations not explicitly specified by the user.
+///
+/// \see InitListExpr
class ImplicitValueInitExpr : public Expr {
public:
explicit ImplicitValueInitExpr(QualType ty)
TST_union,
TST_struct,
TST_class, // C++ class type
- TST_typedef,
+ TST_typename, // Typedef, C++ class-name or enum name, etc.
TST_typeofType,
TST_typeofExpr,
TST_error // erroneous type
case DeclSpec::TST_class: return "class";
case DeclSpec::TST_union: return "union";
case DeclSpec::TST_struct: return "struct";
- case DeclSpec::TST_typedef: return "typedef";
+ case DeclSpec::TST_typename: return "type-name";
case DeclSpec::TST_typeofType:
case DeclSpec::TST_typeofExpr: return "typeof";
}
ConsumeToken(); // The C++ scope.
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
TypeRep);
if (isInvalid)
break;
}
case tok::annot_typename: {
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
Tok.getAnnotationValue());
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
ConsumeToken(); // The typename
NextToken().getKind() == tok::l_paren)
goto DoneWithDeclSpec;
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
TypeRep);
if (isInvalid)
break;
// simple-type-specifier:
case tok::annot_typename: {
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
Tok.getAnnotationValue());
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
ConsumeToken(); // The typename
// type-name
case tok::annot_typename: {
- DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+ DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
Tok.getAnnotationValue());
break;
}
//===--------------------------------------------------------------------===//
// Symbol table / Decl tracking callbacks: SemaDecl.cpp.
//
- virtual DeclTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+ virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, const CXXScopeSpec *SS);
virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup) {
return ActOnDeclarator(S, D, LastInGroup, false);
///
/// This routine performs ordinary name lookup of the identifier II
/// within the given scope, with optional C++ scope specifier SS, to
-/// determine whether the name refers to a type. If so, returns the
-/// declaration corresponding to that type. Otherwise, returns NULL.
+/// determine whether the name refers to a type. If so, returns an
+/// opaque pointer (actually a QualType) corresponding to that
+/// type. Otherwise, returns NULL.
///
/// If name lookup results in an ambiguity, this routine will complain
/// and then return NULL.
-Sema::DeclTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, const CXXScopeSpec *SS) {
Decl *IIDecl = 0;
LookupResult Result = LookupParsedName(S, SS, &II, LookupOrdinaryName, false);
}
if (IIDecl) {
- if (isa<TypedefDecl>(IIDecl) ||
- isa<ObjCInterfaceDecl>(IIDecl) ||
- isa<TagDecl>(IIDecl) ||
- isa<TemplateTypeParmDecl>(IIDecl))
- return IIDecl;
+ if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl))
+ return Context.getTypeDeclType(TD).getAsOpaquePtr();
+ else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl))
+ return Context.getObjCInterfaceType(IDecl).getAsOpaquePtr();
}
return 0;
}
/// 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) {
- TagDecl *Tag
- = dyn_cast_or_null<TagDecl>(static_cast<Decl *>(DS.getTypeRep()));
+ TagDecl *Tag = 0;
+ if (DS.getTypeSpecType() == DeclSpec::TST_class ||
+ DS.getTypeSpecType() == DeclSpec::TST_struct ||
+ DS.getTypeSpecType() == DeclSpec::TST_union ||
+ DS.getTypeSpecType() == DeclSpec::TST_enum)
+ Tag = dyn_cast<TagDecl>(static_cast<Decl *>(DS.getTypeRep()));
+
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
if (!Record->getDeclName() && Record->isDefinition() &&
DS.getStorageClassSpec() != DeclSpec::SCS_typedef)
return DeclarationName(D.getIdentifier());
case Declarator::DK_Constructor: {
- QualType Ty = Context.getTypeDeclType((TypeDecl *)D.getDeclaratorIdType());
+ QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
Ty = Context.getCanonicalType(Ty);
return Context.DeclarationNames.getCXXConstructorName(Ty);
}
case Declarator::DK_Destructor: {
- QualType Ty = Context.getTypeDeclType((TypeDecl *)D.getDeclaratorIdType());
+ QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
Ty = Context.getCanonicalType(Ty);
return Context.DeclarationNames.getCXXDestructorName(Ty);
}
case Declarator::DK_Conversion: {
+ // FIXME: We'd like to keep the non-canonical type for diagnostics!
QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
Ty = Context.getCanonicalType(Ty);
return Context.DeclarationNames.getCXXConversionFunctionName(Ty);
bool Virtual, AccessSpecifier Access,
TypeTy *basetype, SourceLocation BaseLoc) {
CXXRecordDecl *Decl = (CXXRecordDecl*)classdecl;
- QualType BaseType = Context.getTypeDeclType((TypeDecl*)basetype);
+ QualType BaseType = QualType::getFromOpaquePtr(basetype);
// Base specifiers must be record types.
if (!BaseType->isRecordType())
}
if (!isFunc &&
- D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typedef &&
+ D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename &&
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();
+ QualType TDType = QualType::getFromOpaquePtr(DS.getTypeRep());
+ isFunc = TDType->isFunctionType();
}
bool isInstField = ((DS.getStorageClassSpec() == DeclSpec::SCS_unspecified ||
return Diag(IdLoc, diag::err_mem_init_not_member_or_class)
<< MemberOrBase << SourceRange(IdLoc, RParenLoc);
- QualType BaseType = Context.getTypeDeclType((TypeDecl *)BaseTy);
+ QualType BaseType = QualType::getFromOpaquePtr(BaseTy);
if (!BaseType->isRecordType())
return Diag(IdLoc, diag::err_base_init_does_not_name_class)
<< BaseType << SourceRange(IdLoc, RParenLoc);
// (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)) {
+ QualType DeclaratorType = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
+ if (DeclaratorType->getAsTypedefType()) {
Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name)
- << TypedefD->getDeclName();
+ << DeclaratorType;
isInvalid = true;
}
Result = Context.getTypeDeclType(cast<TypeDecl>(D));
break;
}
- case DeclSpec::TST_typedef: {
- Decl *D = static_cast<Decl *>(DS.getTypeRep());
- assert(D && "Didn't get a decl for a typedef?");
+ case DeclSpec::TST_typename: {
assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
DS.getTypeSpecSign() == 0 &&
"Can't handle qualifiers on typedef names yet!");
- DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers();
-
- // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so
- // we have this "hack" for now...
- if (ObjCInterfaceDecl *ObjCIntDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
- if (PQ == 0) {
- Result = Context.getObjCInterfaceType(ObjCIntDecl);
- break;
- }
-
- Result = Context.getObjCQualifiedInterfaceType(ObjCIntDecl,
- (ObjCProtocolDecl**)PQ,
- DS.getNumProtocolQualifiers());
- break;
- } else if (TypedefDecl *typeDecl = dyn_cast<TypedefDecl>(D)) {
- if (Context.getObjCIdType() == Context.getTypedefType(typeDecl) && PQ) {
+ Result = QualType::getFromOpaquePtr(DS.getTypeRep());
+
+ if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
+ // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so
+ // we have this "hack" for now...
+ if (const ObjCInterfaceType *Interface = Result->getAsObjCInterfaceType())
+ Result = Context.getObjCQualifiedInterfaceType(Interface->getDecl(),
+ (ObjCProtocolDecl**)PQ,
+ DS.getNumProtocolQualifiers());
+ else if (Result == Context.getObjCIdType())
// id<protocol-list>
Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ,
DS.getNumProtocolQualifiers());
- break;
- }
}
// TypeQuals handled by caller.
- Result = Context.getTypeDeclType(dyn_cast<TypeDecl>(D));
break;
}
case DeclSpec::TST_typeofType:
// cv-qualifiers are introduced through the use of a typedef
// (7.1.3) or of a template type argument (14.3), in which
// case the cv-qualifiers are ignored.
- if (DS.getTypeSpecType() == DeclSpec::TST_typedef &&
+ // FIXME: Shouldn't we be checking SCS_typedef here?
+ if (DS.getTypeSpecType() == DeclSpec::TST_typename &&
TypeQuals && Result->isReferenceType()) {
TypeQuals &= ~QualType::Const;
TypeQuals &= ~QualType::Volatile;
- (void)m1:(id <MyProtocol> const)arg1;
// FIXME: provide a better diagnostic (no typedef).
-- (void)m2:(id <MyProtocol> short)arg1; // expected-error {{'short typedef' is invalid}}
+- (void)m2:(id <MyProtocol> short)arg1; // expected-error {{'short type-name' is invalid}}
@end
\ No newline at end of file