aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Expr.h6
-rw-r--r--include/clang/Parse/DeclSpec.h2
-rw-r--r--lib/Parse/DeclSpec.cpp2
-rw-r--r--lib/Parse/ParseDecl.cpp8
-rw-r--r--lib/Parse/ParseExprCXX.cpp2
-rw-r--r--lib/Sema/Sema.h2
-rw-r--r--lib/Sema/SemaDecl.cpp30
-rw-r--r--lib/Sema/SemaDeclCXX.cpp16
-rw-r--r--lib/Sema/SemaType.cpp36
-rw-r--r--test/SemaObjC/protocol-archane.m2
10 files changed, 52 insertions, 54 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 4b17929e11..68e486c21b 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -2001,9 +2001,11 @@ public:
/// \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)
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index dc57d57410..83c0d6179f 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -78,7 +78,7 @@ public:
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
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
index d5af384284..4f1ef2490a 100644
--- a/lib/Parse/DeclSpec.cpp
+++ b/lib/Parse/DeclSpec.cpp
@@ -146,7 +146,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
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";
}
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 2ba1edc415..d646ad4cc0 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -492,7 +492,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
ConsumeToken(); // The C++ scope.
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
TypeRep);
if (isInvalid)
break;
@@ -504,7 +504,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
}
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
@@ -554,7 +554,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
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;
@@ -834,7 +834,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
// 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
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 1efa274083..3442d5977a 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -456,7 +456,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
// type-name
case tok::annot_typename: {
- DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+ DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
Tok.getAnnotationValue());
break;
}
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 22599f3f1e..6175e92758 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -283,7 +283,7 @@ public:
//===--------------------------------------------------------------------===//
// 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);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c0160b2d42..4bba5e50f1 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -36,12 +36,13 @@ using namespace clang;
///
/// 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);
@@ -62,11 +63,10 @@ Sema::DeclTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
}
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;
}
@@ -695,8 +695,13 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
/// 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)
@@ -1111,18 +1116,19 @@ DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
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);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index c4c526eedb..02c2e9bbfa 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -318,7 +318,7 @@ Sema::ActOnBaseSpecifier(DeclTy *classdecl, SourceRange SpecifierRange,
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())
@@ -481,15 +481,15 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
}
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 ||
@@ -696,7 +696,7 @@ Sema::ActOnMemInitializer(DeclTy *ConstructorD,
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);
@@ -1149,10 +1149,10 @@ bool Sema::CheckDestructorDeclarator(Declarator &D, QualType &R,
// (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;
}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index d31402de71..25fd5c39fe 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -133,36 +133,25 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
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:
@@ -240,7 +229,8 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
// 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;
diff --git a/test/SemaObjC/protocol-archane.m b/test/SemaObjC/protocol-archane.m
index 67e1c231f6..bfae348f08 100644
--- a/test/SemaObjC/protocol-archane.m
+++ b/test/SemaObjC/protocol-archane.m
@@ -20,5 +20,5 @@ void foo(id x) {
- (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