r251875 - Switch to using an explicit scope object to ensure we don't forget to pop ObjC
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 2 17:19:56 PST 2015
Author: rsmith
Date: Mon Nov 2 19:19:56 2015
New Revision: 251875
URL: http://llvm.org/viewvc/llvm-project?rev=251875&view=rev
Log:
Switch to using an explicit scope object to ensure we don't forget to pop ObjC
type parameters off the scope, and fix the cases where we failed to do so.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/test/SemaObjC/parameterized_classes.m
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=251875&r1=251874&r2=251875&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Nov 2 19:19:56 2015
@@ -1253,12 +1253,12 @@ private:
DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
ParsedAttributes &prefixAttrs);
+ class ObjCTypeParamListScope;
ObjCTypeParamList *parseObjCTypeParamList();
ObjCTypeParamList *parseObjCTypeParamListOrProtocolRefs(
- SourceLocation &lAngleLoc,
- SmallVectorImpl<IdentifierLocPair> &protocolIdents,
- SourceLocation &rAngleLoc,
- bool mayBeProtocolList = true);
+ ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
+ SmallVectorImpl<IdentifierLocPair> &protocolIdents,
+ SourceLocation &rAngleLoc, bool mayBeProtocolList = true);
void HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc,
BalancedDelimiterTracker &T,
Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=251875&r1=251874&r2=251875&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Mon Nov 2 19:19:56 2015
@@ -94,6 +94,28 @@ Parser::DeclGroupPtrTy Parser::ParseObjC
return Actions.ConvertDeclToDeclGroup(SingleDecl);
}
+/// Class to handle popping type parameters when leaving the scope.
+class Parser::ObjCTypeParamListScope {
+ Sema &Actions;
+ Scope *S;
+ ObjCTypeParamList *Params;
+public:
+ ObjCTypeParamListScope(Sema &Actions, Scope *S)
+ : Actions(Actions), S(S), Params(nullptr) {}
+ ~ObjCTypeParamListScope() {
+ leave();
+ }
+ void enter(ObjCTypeParamList *P) {
+ assert(!Params);
+ Params = P;
+ }
+ void leave() {
+ if (Params)
+ Actions.popObjCTypeParamList(S, Params);
+ Params = nullptr;
+ }
+};
+
///
/// objc-class-declaration:
/// '@' 'class' objc-class-forward-decl (',' objc-class-forward-decl)* ';'
@@ -121,11 +143,8 @@ Parser::ParseObjCAtClassDeclaration(Sour
// Parse the optional objc-type-parameter-list.
ObjCTypeParamList *TypeParams = nullptr;
- if (Tok.is(tok::less)) {
+ if (Tok.is(tok::less))
TypeParams = parseObjCTypeParamList();
- if (TypeParams)
- Actions.popObjCTypeParamList(getCurScope(), TypeParams);
- }
ClassTypeParams.push_back(TypeParams);
if (!TryConsumeToken(tok::comma))
break;
@@ -221,11 +240,10 @@ Decl *Parser::ParseObjCAtInterfaceDeclar
SourceLocation LAngleLoc, EndProtoLoc;
SmallVector<IdentifierLocPair, 8> ProtocolIdents;
ObjCTypeParamList *typeParameterList = nullptr;
- if (Tok.is(tok::less)) {
- typeParameterList = parseObjCTypeParamListOrProtocolRefs(LAngleLoc,
- ProtocolIdents,
- EndProtoLoc);
- }
+ ObjCTypeParamListScope typeParamScope(Actions, getCurScope());
+ if (Tok.is(tok::less))
+ typeParameterList = parseObjCTypeParamListOrProtocolRefs(
+ typeParamScope, LAngleLoc, ProtocolIdents, EndProtoLoc);
if (Tok.is(tok::l_paren) &&
!isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { // we have a category.
@@ -286,9 +304,6 @@ Decl *Parser::ParseObjCAtInterfaceDeclar
ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
- if (typeParameterList)
- Actions.popObjCTypeParamList(getCurScope(), typeParameterList);
-
return CategoryType;
}
// Parse a class interface.
@@ -370,9 +385,6 @@ Decl *Parser::ParseObjCAtInterfaceDeclar
ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
- if (typeParameterList)
- Actions.popObjCTypeParamList(getCurScope(), typeParameterList);
-
return ClsType;
}
@@ -432,10 +444,9 @@ static void addContextSensitiveTypeNulla
///
/// \param rAngleLoc The location of the ending '>'.
ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs(
- SourceLocation &lAngleLoc,
- SmallVectorImpl<IdentifierLocPair> &protocolIdents,
- SourceLocation &rAngleLoc,
- bool mayBeProtocolList) {
+ ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
+ SmallVectorImpl<IdentifierLocPair> &protocolIdents,
+ SourceLocation &rAngleLoc, bool mayBeProtocolList) {
assert(Tok.is(tok::less) && "Not at the beginning of a type parameter list");
// Within the type parameter list, don't treat '>' as an operator.
@@ -580,12 +591,13 @@ ObjCTypeParamList *Parser::parseObjCType
makeProtocolIdentsIntoTypeParameters();
}
- // Form the type parameter list.
+ // Form the type parameter list and enter its scope.
ObjCTypeParamList *list = Actions.actOnObjCTypeParamList(
getCurScope(),
lAngleLoc,
typeParams,
rAngleLoc);
+ Scope.enter(list);
// Clear out the angle locations; they're used by the caller to indicate
// whether there are any protocol references.
@@ -599,8 +611,10 @@ ObjCTypeParamList *Parser::parseObjCType
SourceLocation lAngleLoc;
SmallVector<IdentifierLocPair, 1> protocolIdents;
SourceLocation rAngleLoc;
- return parseObjCTypeParamListOrProtocolRefs(lAngleLoc, protocolIdents,
- rAngleLoc,
+
+ ObjCTypeParamListScope Scope(Actions, getCurScope());
+ return parseObjCTypeParamListOrProtocolRefs(Scope, lAngleLoc, protocolIdents,
+ rAngleLoc,
/*mayBeProtocolList=*/false);
}
@@ -2110,8 +2124,9 @@ Parser::ParseObjCAtImplementationDeclara
SourceLocation lAngleLoc, rAngleLoc;
SmallVector<IdentifierLocPair, 8> protocolIdents;
SourceLocation diagLoc = Tok.getLocation();
- if (parseObjCTypeParamListOrProtocolRefs(lAngleLoc, protocolIdents,
- rAngleLoc)) {
+ ObjCTypeParamListScope typeParamScope(Actions, getCurScope());
+ if (parseObjCTypeParamListOrProtocolRefs(typeParamScope, lAngleLoc,
+ protocolIdents, rAngleLoc)) {
Diag(diagLoc, diag::err_objc_parameterized_implementation)
<< SourceRange(diagLoc, PrevTokLocation);
} else if (lAngleLoc.isValid()) {
Modified: cfe/trunk/test/SemaObjC/parameterized_classes.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/parameterized_classes.m?rev=251875&r1=251874&r2=251875&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/parameterized_classes.m (original)
+++ cfe/trunk/test/SemaObjC/parameterized_classes.m Mon Nov 2 19:19:56 2015
@@ -174,6 +174,8 @@ __attribute__((objc_root_class))
@implementation PC1<T : id> (Cat2) // expected-error{{@implementation cannot have type parameters}}
@end
+typedef T undeclaredT; // expected-error{{unknown type name 'T'}}
+
// --------------------------------------------------------------------------
// Interfaces involving type parameters
// --------------------------------------------------------------------------
More information about the cfe-commits
mailing list