forked from OSchip/llvm-project
Tweak implementation for allowing ObjC builtin type redefinitions.
- Replace string comparisons with pre-defined idents. - Avoid calling isBuiltinObjCType() to avoid two checks. - Remove isBuiltinObjCType(), since it was only used in Sema::MergeTypeDefDecl(). - Have Sema::MergeTypeDefDecl() set the new type. This is a moidified version of an patch by David Chisnall. llvm-svn: 55990
This commit is contained in:
parent
58d5ea7ac9
commit
44cfcb6fb1
|
@ -1697,8 +1697,6 @@ void ASTContext::setBuiltinVaListType(QualType T)
|
||||||
|
|
||||||
void ASTContext::setObjCIdType(TypedefDecl *TD)
|
void ASTContext::setObjCIdType(TypedefDecl *TD)
|
||||||
{
|
{
|
||||||
assert(ObjCIdType.isNull() && "'id' type already set!");
|
|
||||||
|
|
||||||
ObjCIdType = getTypedefType(TD);
|
ObjCIdType = getTypedefType(TD);
|
||||||
|
|
||||||
// typedef struct objc_object *id;
|
// typedef struct objc_object *id;
|
||||||
|
@ -1711,8 +1709,6 @@ void ASTContext::setObjCIdType(TypedefDecl *TD)
|
||||||
|
|
||||||
void ASTContext::setObjCSelType(TypedefDecl *TD)
|
void ASTContext::setObjCSelType(TypedefDecl *TD)
|
||||||
{
|
{
|
||||||
assert(ObjCSelType.isNull() && "'SEL' type already set!");
|
|
||||||
|
|
||||||
ObjCSelType = getTypedefType(TD);
|
ObjCSelType = getTypedefType(TD);
|
||||||
|
|
||||||
// typedef struct objc_selector *SEL;
|
// typedef struct objc_selector *SEL;
|
||||||
|
@ -1725,14 +1721,11 @@ void ASTContext::setObjCSelType(TypedefDecl *TD)
|
||||||
|
|
||||||
void ASTContext::setObjCProtoType(QualType QT)
|
void ASTContext::setObjCProtoType(QualType QT)
|
||||||
{
|
{
|
||||||
assert(ObjCProtoType.isNull() && "'Protocol' type already set!");
|
|
||||||
ObjCProtoType = QT;
|
ObjCProtoType = QT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTContext::setObjCClassType(TypedefDecl *TD)
|
void ASTContext::setObjCClassType(TypedefDecl *TD)
|
||||||
{
|
{
|
||||||
assert(ObjCClassType.isNull() && "'Class' type already set!");
|
|
||||||
|
|
||||||
ObjCClassType = getTypedefType(TD);
|
ObjCClassType = getTypedefType(TD);
|
||||||
|
|
||||||
// typedef struct objc_class *Class;
|
// typedef struct objc_class *Class;
|
||||||
|
|
|
@ -21,12 +21,6 @@
|
||||||
|
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
bool Sema::isBuiltinObjCType(TypedefDecl *TD) {
|
|
||||||
const char *typeName = TD->getIdentifier()->getName();
|
|
||||||
return strcmp(typeName, "id") == 0 || strcmp(typeName, "Class") == 0 ||
|
|
||||||
strcmp(typeName, "SEL") == 0 || strcmp(typeName, "Protocol") == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name)
|
static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name)
|
||||||
{
|
{
|
||||||
if (C.getLangOptions().CPlusPlus)
|
if (C.getLangOptions().CPlusPlus)
|
||||||
|
@ -107,6 +101,12 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
|
||||||
|
|
||||||
SuperID = &IT.get("super");
|
SuperID = &IT.get("super");
|
||||||
|
|
||||||
|
// ObjC builtin typedef names.
|
||||||
|
Ident_id = &IT.get("id");
|
||||||
|
Ident_Class = &IT.get("Class");
|
||||||
|
Ident_SEL = &IT.get("SEL");
|
||||||
|
Ident_Protocol = &IT.get("Protocol");
|
||||||
|
|
||||||
TUScope = 0;
|
TUScope = 0;
|
||||||
if (getLangOptions().CPlusPlus)
|
if (getLangOptions().CPlusPlus)
|
||||||
FieldCollector.reset(new CXXFieldCollector());
|
FieldCollector.reset(new CXXFieldCollector());
|
||||||
|
|
|
@ -146,6 +146,10 @@ public:
|
||||||
/// SuperID - Identifier for "super" used for Objective-C checking.
|
/// SuperID - Identifier for "super" used for Objective-C checking.
|
||||||
IdentifierInfo* SuperID;
|
IdentifierInfo* SuperID;
|
||||||
|
|
||||||
|
/// Identifiers for builtin ObjC typedef names.
|
||||||
|
IdentifierInfo *Ident_id, *Ident_Class; // "id", "Class"
|
||||||
|
IdentifierInfo *Ident_SEL, *Ident_Protocol; // "SEL", "Protocol"
|
||||||
|
|
||||||
/// Translation Unit Scope - useful to Objective-C actions that need
|
/// Translation Unit Scope - useful to Objective-C actions that need
|
||||||
/// to lookup file scope declarations in the "ordinary" C decl namespace.
|
/// to lookup file scope declarations in the "ordinary" C decl namespace.
|
||||||
/// For example, user-defined classes, built-in "id" type, etc.
|
/// For example, user-defined classes, built-in "id" type, etc.
|
||||||
|
@ -358,10 +362,6 @@ private:
|
||||||
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
|
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
|
||||||
const ObjCMethodDecl *PrevMethod);
|
const ObjCMethodDecl *PrevMethod);
|
||||||
|
|
||||||
/// isBuiltinObjCType - Returns true of the type is "id", "SEL", "Class"
|
|
||||||
/// or "Protocol".
|
|
||||||
bool isBuiltinObjCType(TypedefDecl *TD);
|
|
||||||
|
|
||||||
/// AddInstanceMethodToGlobalPool - All instance methods in a translation
|
/// AddInstanceMethodToGlobalPool - All instance methods in a translation
|
||||||
/// unit are added to a global pool. This allows us to efficiently associate
|
/// unit are added to a global pool. This allows us to efficiently associate
|
||||||
/// a selector with a method declaraation for purposes of typechecking
|
/// a selector with a method declaraation for purposes of typechecking
|
||||||
|
|
|
@ -230,6 +230,25 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
|
||||||
/// situation, merging decls or emitting diagnostics as appropriate.
|
/// situation, merging decls or emitting diagnostics as appropriate.
|
||||||
///
|
///
|
||||||
TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
|
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.
|
// Verify the old decl was also a typedef.
|
||||||
TypedefDecl *Old = dyn_cast<TypedefDecl>(OldD);
|
TypedefDecl *Old = dyn_cast<TypedefDecl>(OldD);
|
||||||
if (!Old) {
|
if (!Old) {
|
||||||
|
@ -251,11 +270,6 @@ TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
|
||||||
return Old;
|
return Old;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow multiple definitions for ObjC built-in typedefs.
|
|
||||||
// FIXME: Verify the underlying types are equivalent!
|
|
||||||
if (getLangOptions().ObjC1 && isBuiltinObjCType(New))
|
|
||||||
return Old;
|
|
||||||
|
|
||||||
if (getLangOptions().Microsoft) return New;
|
if (getLangOptions().Microsoft) return New;
|
||||||
|
|
||||||
// Redeclaration of a type is a constraint violation (6.7.2.3p1).
|
// Redeclaration of a type is a constraint violation (6.7.2.3p1).
|
||||||
|
|
Loading…
Reference in New Issue