From: Argyrios Kyrtzidis Date: Tue, 29 Sep 2009 19:41:44 +0000 (+0000) Subject: Keep protocol source locations when parsing protocol references. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=71b0addffbdeed29cc062c962e236c34107755d6;p=clang Keep protocol source locations when parsing protocol references. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83091 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index 7ecbf7db7b..7d316c43fd 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -144,6 +144,8 @@ private: // "id". const ActionBase::DeclPtrTy *ProtocolQualifiers; unsigned NumProtocolQualifiers; + SourceLocation ProtocolLAngleLoc; + SourceLocation *ProtocolLocs; // SourceLocation info. These are null if the item wasn't specified or if // the setting was synthesized. @@ -175,11 +177,13 @@ public: TypeRep(0), AttrList(0), ProtocolQualifiers(0), - NumProtocolQualifiers(0) { + NumProtocolQualifiers(0), + ProtocolLocs(0) { } ~DeclSpec() { delete AttrList; delete [] ProtocolQualifiers; + delete [] ProtocolLocs; } // storage-class-specifier SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; } @@ -339,14 +343,21 @@ public: ProtocolQualifierListTy getProtocolQualifiers() const { return ProtocolQualifiers; } + SourceLocation *getProtocolLocs() const { return ProtocolLocs; } unsigned getNumProtocolQualifiers() const { return NumProtocolQualifiers; } - void setProtocolQualifiers(const ActionBase::DeclPtrTy *Protos, unsigned NP) { + SourceLocation getProtocolLAngleLoc() const { return ProtocolLAngleLoc; } + void setProtocolQualifiers(const ActionBase::DeclPtrTy *Protos, unsigned NP, + SourceLocation *ProtoLocs, + SourceLocation LAngleLoc) { if (NP == 0) return; ProtocolQualifiers = new ActionBase::DeclPtrTy[NP]; + ProtocolLocs = new SourceLocation[NP]; memcpy((void*)ProtocolQualifiers, Protos, sizeof(ActionBase::DeclPtrTy)*NP); + memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP); NumProtocolQualifiers = NP; + ProtocolLAngleLoc = LAngleLoc; } /// Finish - This does final analysis of the declspec, issuing diagnostics for diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index e11ca0ce6b..9cb4677f66 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -674,7 +674,9 @@ private: void ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, SourceLocation atLoc); bool ParseObjCProtocolReferences(llvm::SmallVectorImpl &P, + llvm::SmallVectorImpl &PLocs, bool WarnOnDeclarations, + SourceLocation &LAngleLoc, SourceLocation &EndProtoLoc); void ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl, tok::ObjCKeywordKind contextKey); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index d885558e1f..e15a4cd688 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -848,10 +848,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (!Tok.is(tok::less) || !getLang().ObjC1) continue; - SourceLocation EndProtoLoc; + SourceLocation LAngleLoc, EndProtoLoc; llvm::SmallVector ProtocolDecl; - ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc); - DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size()); + llvm::SmallVector ProtocolLocs; + ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false, + LAngleLoc, EndProtoLoc); + DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(), + ProtocolLocs.data(), LAngleLoc); DS.SetRangeEnd(EndProtoLoc); continue; @@ -908,10 +911,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (!Tok.is(tok::less) || !getLang().ObjC1) continue; - SourceLocation EndProtoLoc; + SourceLocation LAngleLoc, EndProtoLoc; llvm::SmallVector ProtocolDecl; - ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc); - DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size()); + llvm::SmallVector ProtocolLocs; + ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false, + LAngleLoc, EndProtoLoc); + DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(), + ProtocolLocs.data(), LAngleLoc); DS.SetRangeEnd(EndProtoLoc); @@ -1154,10 +1160,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, goto DoneWithDeclSpec; { - SourceLocation EndProtoLoc; + SourceLocation LAngleLoc, EndProtoLoc; llvm::SmallVector ProtocolDecl; - ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc); - DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size()); + llvm::SmallVector ProtocolLocs; + ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false, + LAngleLoc, EndProtoLoc); + DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(), + ProtocolLocs.data(), LAngleLoc); DS.SetRangeEnd(EndProtoLoc); Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id) @@ -1268,10 +1277,13 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, if (!Tok.is(tok::less) || !getLang().ObjC1) return true; - SourceLocation EndProtoLoc; + SourceLocation LAngleLoc, EndProtoLoc; llvm::SmallVector ProtocolDecl; - ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc); - DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size()); + llvm::SmallVector ProtocolLocs; + ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false, + LAngleLoc, EndProtoLoc); + DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(), + ProtocolLocs.data(), LAngleLoc); DS.SetRangeEnd(EndProtoLoc); return true; diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index fdd031c66d..014f10edd4 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -148,10 +148,12 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( rparenLoc = ConsumeParen(); // Next, we need to check for any protocol references. - SourceLocation EndProtoLoc; + SourceLocation LAngleLoc, EndProtoLoc; llvm::SmallVector ProtocolRefs; + llvm::SmallVector ProtocolLocs; if (Tok.is(tok::less) && - ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc)) + ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, + LAngleLoc, EndProtoLoc)) return DeclPtrTy(); if (attrList) // categories don't support attributes. @@ -183,9 +185,11 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( } // Next, we need to check for any protocol references. llvm::SmallVector ProtocolRefs; - SourceLocation EndProtoLoc; + llvm::SmallVector ProtocolLocs; + SourceLocation LAngleLoc, EndProtoLoc; if (Tok.is(tok::less) && - ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc)) + ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, + LAngleLoc, EndProtoLoc)) return DeclPtrTy(); DeclPtrTy ClsType = @@ -786,10 +790,12 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, /// bool Parser:: ParseObjCProtocolReferences(llvm::SmallVectorImpl &Protocols, - bool WarnOnDeclarations, SourceLocation &EndLoc) { + llvm::SmallVectorImpl &ProtocolLocs, + bool WarnOnDeclarations, + SourceLocation &LAngleLoc, SourceLocation &EndLoc) { assert(Tok.is(tok::less) && "expected <"); - ConsumeToken(); // the "<" + LAngleLoc = ConsumeToken(); // the "<" llvm::SmallVector ProtocolIdents; @@ -801,6 +807,7 @@ ParseObjCProtocolReferences(llvm::SmallVectorImpl &Protocols, } ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation())); + ProtocolLocs.push_back(Tok.getLocation()); ConsumeToken(); if (Tok.isNot(tok::comma)) @@ -982,11 +989,13 @@ Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, } // Last, and definitely not least, parse a protocol declaration. - SourceLocation EndProtoLoc; + SourceLocation LAngleLoc, EndProtoLoc; llvm::SmallVector ProtocolRefs; + llvm::SmallVector ProtocolLocs; if (Tok.is(tok::less) && - ParseObjCProtocolReferences(ProtocolRefs, false, EndProtoLoc)) + ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false, + LAngleLoc, EndProtoLoc)) return DeclPtrTy(); DeclPtrTy ProtoType =