forked from OSchip/llvm-project
objc: Implemented variables declared in class interface
whose sema decl is at the translation unit. llvm-svn: 67249
This commit is contained in:
parent
6c17bfd99b
commit
3654e65adf
|
@ -246,6 +246,11 @@ public:
|
||||||
///
|
///
|
||||||
class ObjCContainerDecl : public NamedDecl, public DeclContext {
|
class ObjCContainerDecl : public NamedDecl, public DeclContext {
|
||||||
SourceLocation AtEndLoc; // marks the end of the method container.
|
SourceLocation AtEndLoc; // marks the end of the method container.
|
||||||
|
// FIXME. In the long term, all TU variables declared in class scope belong
|
||||||
|
// to class's decl context. This waits till we can establish class's
|
||||||
|
// context before processing all decls in the class.
|
||||||
|
/// Instance variables in the interface.
|
||||||
|
ObjCList<VarDecl> TUVars;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
||||||
|
@ -298,7 +303,15 @@ public:
|
||||||
ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
|
ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
|
||||||
return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
|
return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef ObjCList<VarDecl>::iterator tuvar_iterator;
|
||||||
|
tuvar_iterator tuvar_begin() const { return TUVars.begin(); }
|
||||||
|
tuvar_iterator tuvar_end() const { return TUVars.end(); }
|
||||||
|
unsigned tuvar_size() const { return TUVars.size(); }
|
||||||
|
void setTUVarList(VarDecl * const *List, unsigned Num, ASTContext &C) {
|
||||||
|
TUVars.set(List, Num, C);
|
||||||
|
}
|
||||||
|
|
||||||
ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
|
ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
|
||||||
|
|
||||||
// Marks the end of the container.
|
// Marks the end of the container.
|
||||||
|
|
|
@ -1366,7 +1366,9 @@ public:
|
||||||
DeclTy **allMethods = 0,
|
DeclTy **allMethods = 0,
|
||||||
unsigned allNum = 0,
|
unsigned allNum = 0,
|
||||||
DeclTy **allProperties = 0,
|
DeclTy **allProperties = 0,
|
||||||
unsigned pNum = 0) {
|
unsigned pNum = 0,
|
||||||
|
DeclTy **allTUVars = 0,
|
||||||
|
unsigned tuvNum = 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// ActOnProperty - called to build one property AST
|
// ActOnProperty - called to build one property AST
|
||||||
|
|
|
@ -1234,16 +1234,24 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
|
||||||
|
|
||||||
// Objective-C Decls
|
// Objective-C Decls
|
||||||
|
|
||||||
// Forward declarations, no (immediate) code generation.
|
// Forward declarations, no (immediate) code generation.
|
||||||
case Decl::ObjCClass:
|
case Decl::ObjCClass:
|
||||||
case Decl::ObjCCategory:
|
|
||||||
case Decl::ObjCForwardProtocol:
|
case Decl::ObjCForwardProtocol:
|
||||||
case Decl::ObjCInterface:
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Decl::ObjCProtocol:
|
case Decl::ObjCProtocol:
|
||||||
Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
|
case Decl::ObjCCategory:
|
||||||
|
case Decl::ObjCInterface: {
|
||||||
|
ObjCContainerDecl *OCD = cast<ObjCContainerDecl>(D);
|
||||||
|
for (ObjCContainerDecl::tuvar_iterator i = OCD->tuvar_begin(),
|
||||||
|
e = OCD->tuvar_end(); i != e; ++i) {
|
||||||
|
VarDecl *VD = *i;
|
||||||
|
EmitGlobal(VD);
|
||||||
|
}
|
||||||
|
if (D->getKind() == Decl::ObjCProtocol)
|
||||||
|
Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Decl::ObjCCategoryImpl:
|
case Decl::ObjCCategoryImpl:
|
||||||
// Categories have properties but don't support synthesize so we
|
// Categories have properties but don't support synthesize so we
|
||||||
|
|
|
@ -215,6 +215,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
|
||||||
tok::ObjCKeywordKind contextKey) {
|
tok::ObjCKeywordKind contextKey) {
|
||||||
llvm::SmallVector<DeclTy*, 32> allMethods;
|
llvm::SmallVector<DeclTy*, 32> allMethods;
|
||||||
llvm::SmallVector<DeclTy*, 16> allProperties;
|
llvm::SmallVector<DeclTy*, 16> allProperties;
|
||||||
|
llvm::SmallVector<DeclTy*, 8> allTUVariables;
|
||||||
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
|
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
|
||||||
|
|
||||||
SourceLocation AtEndLoc;
|
SourceLocation AtEndLoc;
|
||||||
|
@ -252,7 +253,8 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
|
||||||
|
|
||||||
// FIXME: as the name implies, this rule allows function definitions.
|
// FIXME: as the name implies, this rule allows function definitions.
|
||||||
// We could pass a flag or check for functions during semantic analysis.
|
// We could pass a flag or check for functions during semantic analysis.
|
||||||
ParseDeclarationOrFunctionDefinition();
|
DeclTy *VFDecl = ParseDeclarationOrFunctionDefinition();
|
||||||
|
allTUVariables.push_back(VFDecl);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +362,10 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
|
||||||
allMethods.empty() ? 0 : &allMethods[0],
|
allMethods.empty() ? 0 : &allMethods[0],
|
||||||
allMethods.size(),
|
allMethods.size(),
|
||||||
allProperties.empty() ? 0 : &allProperties[0],
|
allProperties.empty() ? 0 : &allProperties[0],
|
||||||
allProperties.size());
|
allProperties.size(),
|
||||||
|
allTUVariables.empty() ? 0 :
|
||||||
|
&allTUVariables[0],
|
||||||
|
allTUVariables.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse property attribute declarations.
|
/// Parse property attribute declarations.
|
||||||
|
|
|
@ -1986,7 +1986,8 @@ public:
|
||||||
|
|
||||||
virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
||||||
DeclTy **allMethods = 0, unsigned allNum = 0,
|
DeclTy **allMethods = 0, unsigned allNum = 0,
|
||||||
DeclTy **allProperties = 0, unsigned pNum = 0);
|
DeclTy **allProperties = 0, unsigned pNum = 0,
|
||||||
|
DeclTy **allTUVars = 0, unsigned tuvNum = 0);
|
||||||
|
|
||||||
virtual DeclTy *ActOnProperty(Scope *S, SourceLocation AtLoc,
|
virtual DeclTy *ActOnProperty(Scope *S, SourceLocation AtLoc,
|
||||||
FieldDeclarator &FD, ObjCDeclSpec &ODS,
|
FieldDeclarator &FD, ObjCDeclSpec &ODS,
|
||||||
|
|
|
@ -1233,7 +1233,9 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
|
||||||
// always null.
|
// always null.
|
||||||
void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
||||||
DeclTy **allMethods, unsigned allNum,
|
DeclTy **allMethods, unsigned allNum,
|
||||||
DeclTy **allProperties, unsigned pNum) {
|
DeclTy **allProperties, unsigned pNum,
|
||||||
|
DeclTy **allTUVars,
|
||||||
|
unsigned tuvNum) {
|
||||||
Decl *ClassDecl = static_cast<Decl *>(classDecl);
|
Decl *ClassDecl = static_cast<Decl *>(classDecl);
|
||||||
|
|
||||||
// FIXME: If we don't have a ClassDecl, we have an error. We should consider
|
// FIXME: If we don't have a ClassDecl, we have an error. We should consider
|
||||||
|
@ -1337,6 +1339,15 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
llvm::SmallVector<VarDecl*, 8> allTUVariables;
|
||||||
|
for (unsigned i = 0; i < tuvNum; i++) {
|
||||||
|
if (VarDecl *VD = dyn_cast<VarDecl>((Decl*)allTUVars[i]))
|
||||||
|
allTUVariables.push_back(VD);
|
||||||
|
}
|
||||||
|
if (!allTUVariables.empty() && isInterfaceDeclKind) {
|
||||||
|
ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(ClassDecl);
|
||||||
|
OCD->setTUVarList(&allTUVariables[0], allTUVariables.size(), Context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
// RUN: clang -fnext-runtime -emit-llvm -o %t %s
|
||||||
|
// RUN: grep 'two = global' %t &&
|
||||||
|
// RUN: grep 'ddd = common' %t &&
|
||||||
|
// RUN: grep 'III = common' %t
|
||||||
|
|
||||||
|
@interface XX
|
||||||
|
int x;
|
||||||
|
int one=1;
|
||||||
|
int two = 2;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@protocol PPP
|
||||||
|
int ddd;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface XX(CAT)
|
||||||
|
char * III;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
int main( int argc, const char *argv[] ) {
|
||||||
|
return x+one+two;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue