Fairly large "cleaup" related to changing ObjCCompatibleAliasDecl superclass (to inherit from NamedDecl, instead of ScopedDecl).
- Added a DenseMap to associate an IdentifierInfo with the ObjCCompatibleAliasDecl.
- Renamed LookupScopedDecl->LookupDecl and changed it's return type to Decl. Also added lookup for ObjCCompatibleAliasDecl's.
- Removed Sema::LookupInterfaceDecl(). Converted clients to used LookupDecl().
- Some minor indentation changes.
Will deal with ObjCInterfaceDecl and getObjCInterfaceDecl() in a separate commit...
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49058 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index bad65cf..4c8f6b8 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -343,10 +343,6 @@
if (isa<FunctionDecl>(this))
return true;
- // FIXME: Why is ObjCCompatibleAlias a scopedecl?
- if (isa<ObjCCompatibleAliasDecl>(this))
- return true;
-
// FIXME: This needs to check the context the decl was defined in!
if (isa<TypeDecl>(this) || isa<EnumConstantDecl>(this))
return true;
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index fc81781..e30f4b2 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -32,6 +32,7 @@
class ASTConsumer;
class Preprocessor;
class Decl;
+ class NamedDecl;
class ScopedDecl;
class Expr;
class InitListExpr;
@@ -51,6 +52,7 @@
class OCUVectorType;
class TypedefDecl;
class ObjCInterfaceDecl;
+ class ObjCCompatibleAliasDecl;
class ObjCProtocolDecl;
class ObjCImplementationDecl;
class ObjCCategoryImplDecl;
@@ -93,6 +95,13 @@
/// find the declarations when needed.
llvm::DenseMap<IdentifierInfo*, ObjCProtocolDecl*> ObjCProtocols;
+ /// ObjCAliasDecls - Keep track of all class declarations declared
+ /// with @compatibility_alias, so that we can emit errors on duplicates and
+ /// find the declarations when needed. This construct is ancient and will
+ /// likely never be seen. Nevertheless, it is here for compatibility.
+ typedef llvm::DenseMap<IdentifierInfo*, ObjCCompatibleAliasDecl*> ObjCAliasTy;
+ ObjCAliasTy ObjCAliasDecls;
+
// Enum values used by KnownFunctionIDs (see below).
enum {
id_printf,
@@ -232,16 +241,15 @@
/// Subroutines of ActOnDeclarator().
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
ScopedDecl *LastDecl);
- TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, ScopedDecl *Old);
- FunctionDecl *MergeFunctionDecl(FunctionDecl *New, ScopedDecl *Old);
- VarDecl *MergeVarDecl(VarDecl *New, ScopedDecl *Old);
+ TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
+ FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old);
+ VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
/// More parsing and symbol table subroutines...
ParmVarDecl *ActOnParamDeclarator(struct DeclaratorChunk::ParamInfo &PI,
Scope *FnBodyScope);
- ScopedDecl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI,
- SourceLocation IdLoc, Scope *S);
- ScopedDecl *LookupInterfaceDecl(IdentifierInfo *II);
+ Decl *LookupDecl(IdentifierInfo *II, unsigned NSI,
+ SourceLocation IdLoc, Scope *S);
ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S);
ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9429d4b..0280ef2 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -35,15 +35,22 @@
Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
Decl *IIDecl = II.getFETokenInfo<Decl>();
// Find first occurance of none-tagged declaration
- while(IIDecl && IIDecl->getIdentifierNamespace() != Decl::IDNS_Ordinary)
+ while (IIDecl && IIDecl->getIdentifierNamespace() != Decl::IDNS_Ordinary)
IIDecl = cast<ScopedDecl>(IIDecl)->getNext();
- if (!IIDecl)
+
+ if (!IIDecl) {
+ if (getLangOptions().ObjC1) {
+ // @interface and @compatibility_alias result in new type references.
+ // Creating a class alias is *extremely* rare.
+ ObjCAliasTy::const_iterator I = ObjCAliasDecls.find((IdentifierInfo*)&II);
+ if (I != ObjCAliasDecls.end())
+ return I->second->getClassInterface();
+ }
return 0;
+ }
+ // FIXME: remove ObjCInterfaceDecl check when we make it a named decl.
if (isa<TypedefDecl>(IIDecl) || isa<ObjCInterfaceDecl>(IIDecl))
return IIDecl;
- if (ObjCCompatibleAliasDecl *ADecl =
- dyn_cast<ObjCCompatibleAliasDecl>(IIDecl))
- return ADecl->getClassInterface();
return 0;
}
@@ -91,15 +98,14 @@
}
}
-/// LookupInterfaceDecl - Lookup interface declaration in the scope chain.
-/// Return the first declaration found (which may or may not be a class
-/// declaration. Caller is responsible for handling the none-class case.
-/// Bypassing the alias of a class by returning the aliased class.
-ScopedDecl *Sema::LookupInterfaceDecl(IdentifierInfo *ClassName) {
+/// getObjCInterfaceDecl - Look up a for a class declaration in the scope.
+/// return 0 if one not found.
+/// FIXME: removed this when ObjCInterfaceDecl's aren't ScopedDecl's.
+ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
ScopedDecl *IDecl;
// Scan up the scope chain looking for a decl that matches this identifier
// that is in the appropriate namespace.
- for (IDecl = ClassName->getFETokenInfo<ScopedDecl>(); IDecl;
+ for (IDecl = Id->getFETokenInfo<ScopedDecl>(); IDecl;
IDecl = IDecl->getNext())
if (IDecl->getIdentifierNamespace() == Decl::IDNS_Ordinary)
break;
@@ -107,20 +113,13 @@
if (ObjCCompatibleAliasDecl *ADecl =
dyn_cast_or_null<ObjCCompatibleAliasDecl>(IDecl))
return ADecl->getClassInterface();
- return IDecl;
+ return cast_or_null<ObjCInterfaceDecl>(IDecl);
}
-/// getObjCInterfaceDecl - Look up a for a class declaration in the scope.
-/// return 0 if one not found.
-ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
- ScopedDecl *IdDecl = LookupInterfaceDecl(Id);
- return cast_or_null<ObjCInterfaceDecl>(IdDecl);
-}
-
-/// LookupScopedDecl - Look up the inner-most declaration in the specified
+/// LookupDecl - Look up the inner-most declaration in the specified
/// namespace.
-ScopedDecl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI,
- SourceLocation IdLoc, Scope *S) {
+Decl *Sema::LookupDecl(IdentifierInfo *II, unsigned NSI,
+ SourceLocation IdLoc, Scope *S) {
if (II == 0) return 0;
Decl::IdentifierNamespace NS = (Decl::IdentifierNamespace)NSI;
@@ -138,6 +137,16 @@
// If this is a builtin on this (or all) targets, create the decl.
if (unsigned BuiltinID = II->getBuiltinID())
return LazilyCreateBuiltin(II, BuiltinID, S);
+
+ if (getLangOptions().ObjC1) {
+ // @interface and @compatibility_alias introduce typedef-like names.
+ // Unlike typedef's, they can only be introduced at file-scope (and are
+ // not therefore not scoped decls). They can, however, be shadowed by
+ // other names in IDNS_Ordinary.
+ ObjCAliasTy::iterator I = ObjCAliasDecls.find(II);
+ if (I != ObjCAliasDecls.end())
+ return I->second->getClassInterface();
+ }
}
return 0;
}
@@ -148,8 +157,8 @@
return;
IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
- ScopedDecl *VaDecl = LookupScopedDecl(VaIdent, Decl::IDNS_Ordinary,
- SourceLocation(), TUScope);
+ Decl *VaDecl = LookupDecl(VaIdent, Decl::IDNS_Ordinary,
+ SourceLocation(), TUScope);
TypedefDecl *VaTypedef = cast<TypedefDecl>(VaDecl);
Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
}
@@ -193,7 +202,7 @@
/// and scope as a previous declaration 'Old'. Figure out how to resolve this
/// situation, merging decls or emitting diagnostics as appropriate.
///
-TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, ScopedDecl *OldD) {
+TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
// Verify the old decl was also a typedef.
TypedefDecl *Old = dyn_cast<TypedefDecl>(OldD);
if (!Old) {
@@ -265,7 +274,7 @@
/// and scope as a previous declaration 'Old'. Figure out how to resolve this
/// situation, merging decls or emitting diagnostics as appropriate.
///
-FunctionDecl *Sema::MergeFunctionDecl(FunctionDecl *New, ScopedDecl *OldD) {
+FunctionDecl *Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
// Verify the old decl was also a function.
FunctionDecl *Old = dyn_cast<FunctionDecl>(OldD);
if (!Old) {
@@ -337,7 +346,7 @@
/// FIXME: Need to carefully consider tentative definition rules (C99 6.9.2p2).
/// For example, we incorrectly complain about i1, i4 from C99 6.9.2p4.
///
-VarDecl *Sema::MergeVarDecl(VarDecl *New, ScopedDecl *OldD) {
+VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
// Verify the old decl was also a variable.
VarDecl *Old = dyn_cast<VarDecl>(OldD);
if (!Old) {
@@ -707,8 +716,7 @@
S = S->getParent();
// See if this is a redefinition of a variable in the same scope.
- ScopedDecl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary,
- D.getIdentifierLoc(), S);
+ Decl *PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, D.getIdentifierLoc(), S);
ScopedDecl *New;
bool InvalidDecl = false;
@@ -980,8 +988,8 @@
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
// Can this happen for params? We already checked that they don't conflict
// among each other. Here they can only shadow globals, which is ok.
- if (/*Decl *PrevDecl = */LookupScopedDecl(II, Decl::IDNS_Ordinary,
- PI.IdentLoc, FnScope)) {
+ if (/*Decl *PrevDecl = */LookupDecl(II, Decl::IDNS_Ordinary,
+ PI.IdentLoc, FnScope)) {
}
@@ -1061,8 +1069,8 @@
Scope *GlobalScope = FnBodyScope->getParent();
// See if this is a redefinition.
- ScopedDecl *PrevDcl = LookupScopedDecl(D.getIdentifier(), Decl::IDNS_Ordinary,
- D.getIdentifierLoc(), GlobalScope);
+ Decl *PrevDcl = LookupDecl(D.getIdentifier(), Decl::IDNS_Ordinary,
+ D.getIdentifierLoc(), GlobalScope);
if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(PrevDcl)) {
if (FD->getBody()) {
Diag(D.getIdentifierLoc(), diag::err_redefinition,
@@ -1216,8 +1224,8 @@
// If this is a named struct, check to see if there was a previous forward
// declaration or definition.
if (TagDecl *PrevDecl =
- dyn_cast_or_null<TagDecl>(LookupScopedDecl(Name, Decl::IDNS_Tag,
- NameLoc, S))) {
+ dyn_cast_or_null<TagDecl>(LookupDecl(Name, Decl::IDNS_Tag,
+ NameLoc, S))) {
// If this is a use of a previous tag, or if the tag is already declared in
// the same scope (so that the definition/declaration completes or
@@ -1540,8 +1548,7 @@
// Verify that there isn't already something declared with this name in this
// scope.
- if (ScopedDecl *PrevDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary,
- IdLoc, S)) {
+ if (Decl *PrevDecl = LookupDecl(Id, Decl::IDNS_Ordinary, IdLoc, S)) {
if (S->isDeclScope(PrevDecl)) {
if (isa<EnumConstantDecl>(PrevDecl))
Diag(IdLoc, diag::err_redefinition_of_enumerator, Id->getName());
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 1270653..2385cd0 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -79,7 +79,7 @@
assert(ClassName && "Missing class identifier");
// Check for another declaration kind with the same name.
- ScopedDecl *PrevDecl = LookupInterfaceDecl(ClassName);
+ Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, ClassLoc,TUScope);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(ClassLoc, diag::err_redefinition_different_kind,
ClassName->getName());
@@ -112,7 +112,7 @@
if (SuperName) {
ObjCInterfaceDecl* SuperClassEntry = 0;
// Check if a different kind of symbol declared in this scope.
- PrevDecl = LookupInterfaceDecl(SuperName);
+ PrevDecl = LookupDecl(SuperName, Decl::IDNS_Ordinary, SuperLoc, TUScope);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(SuperLoc, diag::err_redefinition_different_kind,
SuperName->getName());
@@ -152,13 +152,14 @@
/// ActOnCompatiblityAlias - this action is called after complete parsing of
/// @compaatibility_alias declaration. It sets up the alias relationships.
-Sema::DeclTy *Sema::ActOnCompatiblityAlias(
- SourceLocation AtCompatibilityAliasLoc,
- IdentifierInfo *AliasName, SourceLocation AliasLocation,
- IdentifierInfo *ClassName, SourceLocation ClassLocation) {
+Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
+ IdentifierInfo *AliasName,
+ SourceLocation AliasLocation,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassLocation) {
// Look for previous declaration of alias name
- ScopedDecl *ADecl = LookupScopedDecl(AliasName, Decl::IDNS_Ordinary,
- AliasLocation, TUScope);
+ Decl *ADecl = LookupDecl(AliasName, Decl::IDNS_Ordinary,
+ AliasLocation, TUScope);
if (ADecl) {
if (isa<ObjCCompatibleAliasDecl>(ADecl)) {
Diag(AliasLocation, diag::warn_previous_alias_decl);
@@ -172,8 +173,8 @@
return 0;
}
// Check for class declaration
- ScopedDecl *CDeclU = LookupScopedDecl(ClassName, Decl::IDNS_Ordinary,
- ClassLocation, TUScope);
+ Decl *CDeclU = LookupDecl(ClassName, Decl::IDNS_Ordinary,
+ ClassLocation, TUScope);
ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU);
if (CDecl == 0) {
Diag(ClassLocation, diag::warn_undef_interface, ClassName->getName());
@@ -184,12 +185,10 @@
// Everything checked out, instantiate a new alias declaration AST.
ObjCCompatibleAliasDecl *AliasDecl =
- ObjCCompatibleAliasDecl::Create(Context, AtCompatibilityAliasLoc,
- AliasName, CDecl);
-
- // Chain & install the interface decl into the identifier.
- AliasDecl->setNext(AliasName->getFETokenInfo<ScopedDecl>());
- AliasName->setFETokenInfo(AliasDecl);
+ ObjCCompatibleAliasDecl::Create(Context, AtLoc, AliasName, CDecl);
+
+ ObjCAliasDecls[AliasName] = AliasDecl;
+ TUScope->AddDecl(AliasDecl);
return AliasDecl;
}
@@ -348,7 +347,7 @@
SourceLocation SuperClassLoc) {
ObjCInterfaceDecl* IDecl = 0;
// Check for another declaration kind with the same name.
- ScopedDecl *PrevDecl = LookupInterfaceDecl(ClassName);
+ Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, ClassLoc,TUScope);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(ClassLoc, diag::err_redefinition_different_kind,
ClassName->getName());
@@ -365,7 +364,8 @@
ObjCInterfaceDecl* SDecl = 0;
if (SuperClassname) {
// Check if a different kind of symbol declared in this scope.
- PrevDecl = LookupInterfaceDecl(SuperClassname);
+ PrevDecl = LookupDecl(SuperClassname, Decl::IDNS_Ordinary,
+ SuperClassLoc, TUScope);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(SuperClassLoc, diag::err_redefinition_different_kind,
SuperClassname->getName());
@@ -590,7 +590,8 @@
for (unsigned i = 0; i != NumElts; ++i) {
// Check for another declaration kind with the same name.
- ScopedDecl *PrevDecl = LookupInterfaceDecl(IdentList[i]);
+ Decl *PrevDecl = LookupDecl(IdentList[i], Decl::IDNS_Ordinary,
+ AtClassLoc, TUScope);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(AtClassLoc, diag::err_redefinition_different_kind,
IdentList[i]->getName());
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index c815b54..94387da 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -75,17 +75,18 @@
IdentifierInfo &II,
bool HasTrailingLParen) {
// Could be enum-constant, value decl, instance variable, etc.
- ScopedDecl *D = LookupScopedDecl(&II, Decl::IDNS_Ordinary, Loc, S);
+ Decl *D = LookupDecl(&II, Decl::IDNS_Ordinary, Loc, S);
// If this reference is in an Objective-C method, then ivar lookup happens as
// well.
if (CurMethodDecl) {
+ ScopedDecl *SD = dyn_cast_or_null<ScopedDecl>(D);
// There are two cases to handle here. 1) scoped lookup could have failed,
// in which case we should look for an ivar. 2) scoped lookup could have
// found a decl, but that decl is outside the current method (i.e. a global
// variable). In these two cases, we do a lookup for an ivar with this
// name, if the lookup suceeds, we replace it our current decl.
- if (D == 0 || D->isDefinedOutsideFunctionOrMethod()) {
+ if (SD == 0 || SD->isDefinedOutsideFunctionOrMethod()) {
ObjCInterfaceDecl *IFace = CurMethodDecl->getClassInterface(), *DeclClass;
if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&II, DeclClass)) {
// FIXME: This should use a new expr for a direct reference, don't turn
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 1a274e1..00a1318 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -52,8 +52,8 @@
// Initialize the constant string interface lazily. This assumes
// the NSConstantString interface is seen in this translation unit.
IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString");
- ScopedDecl *IFace = LookupScopedDecl(NSIdent, Decl::IDNS_Ordinary,
- SourceLocation(), TUScope);
+ Decl *IFace = LookupDecl(NSIdent, Decl::IDNS_Ordinary,
+ SourceLocation(), TUScope);
ObjCInterfaceDecl *strIFace = dyn_cast_or_null<ObjCInterfaceDecl>(IFace);
if (!strIFace)
return Diag(S->getLocStart(), diag::err_undef_interface,