r247462 - [Edit] Fix issue with tracking what macro argument inputs have been edited.
Argyrios Kyrtzidis via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 11 13:09:11 PDT 2015
Author: akirtzidis
Date: Fri Sep 11 15:09:11 2015
New Revision: 247462
URL: http://llvm.org/viewvc/llvm-project?rev=247462&view=rev
Log:
[Edit] Fix issue with tracking what macro argument inputs have been edited.
This was not working correctly, leading to erroneously rejecting valid edits.
Modified:
cfe/trunk/include/clang/Edit/EditedSource.h
cfe/trunk/lib/Edit/EditedSource.cpp
cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m
cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result
Modified: cfe/trunk/include/clang/Edit/EditedSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Edit/EditedSource.h?rev=247462&r1=247461&r2=247462&view=diff
==============================================================================
--- cfe/trunk/include/clang/Edit/EditedSource.h (original)
+++ cfe/trunk/include/clang/Edit/EditedSource.h Fri Sep 11 15:09:11 2015
@@ -10,9 +10,11 @@
#ifndef LLVM_CLANG_EDIT_EDITEDSOURCE_H
#define LLVM_CLANG_EDIT_EDITEDSOURCE_H
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Edit/FileOffset.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
#include <map>
@@ -39,14 +41,18 @@ class EditedSource {
typedef std::map<FileOffset, FileEdit> FileEditsTy;
FileEditsTy FileEdits;
- llvm::DenseMap<unsigned, SourceLocation> ExpansionToArgMap;
+ llvm::DenseMap<unsigned, llvm::TinyPtrVector<IdentifierInfo*>>
+ ExpansionToArgMap;
+ SmallVector<std::pair<SourceLocation, IdentifierInfo*>, 2>
+ CurrCommitMacroArgExps;
+ IdentifierTable IdentTable;
llvm::BumpPtrAllocator StrAlloc;
public:
EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
const PPConditionalDirectiveRecord *PPRec = nullptr)
- : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec),
+ : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), IdentTable(LangOpts),
StrAlloc() { }
const SourceManager &getSourceManager() const { return SourceMgr; }
@@ -76,6 +82,12 @@ private:
StringRef getSourceText(FileOffset BeginOffs, FileOffset EndOffs,
bool &Invalid);
FileEditsTy::iterator getActionForOffset(FileOffset Offs);
+ void deconstructMacroArgLoc(SourceLocation Loc,
+ SourceLocation &ExpansionLoc,
+ IdentifierInfo *&II);
+
+ void startingCommit();
+ void finishedCommit();
};
}
Modified: cfe/trunk/lib/Edit/EditedSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Edit/EditedSource.cpp?rev=247462&r1=247461&r2=247462&view=diff
==============================================================================
--- cfe/trunk/lib/Edit/EditedSource.cpp (original)
+++ cfe/trunk/lib/Edit/EditedSource.cpp Fri Sep 11 15:09:11 2015
@@ -23,6 +23,36 @@ void EditsReceiver::remove(CharSourceRan
replace(range, StringRef());
}
+void EditedSource::deconstructMacroArgLoc(SourceLocation Loc,
+ SourceLocation &ExpansionLoc,
+ IdentifierInfo *&II) {
+ assert(SourceMgr.isMacroArgExpansion(Loc));
+ SourceLocation DefArgLoc = SourceMgr.getImmediateExpansionRange(Loc).first;
+ ExpansionLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
+ SmallString<20> Buf;
+ StringRef ArgName = Lexer::getSpelling(SourceMgr.getSpellingLoc(DefArgLoc),
+ Buf, SourceMgr, LangOpts);
+ II = nullptr;
+ if (!ArgName.empty()) {
+ II = &IdentTable.get(ArgName);
+ }
+}
+
+void EditedSource::startingCommit() {}
+
+void EditedSource::finishedCommit() {
+ for (auto &ExpArg : CurrCommitMacroArgExps) {
+ SourceLocation ExpLoc;
+ IdentifierInfo *II;
+ std::tie(ExpLoc, II) = ExpArg;
+ auto &ArgNames = ExpansionToArgMap[ExpLoc.getRawEncoding()];
+ if (std::find(ArgNames.begin(), ArgNames.end(), II) == ArgNames.end()) {
+ ArgNames.push_back(II);
+ }
+ }
+ CurrCommitMacroArgExps.clear();
+}
+
StringRef EditedSource::copyString(const Twine &twine) {
SmallString<128> Data;
return copyString(twine.toStringRef(Data));
@@ -36,15 +66,27 @@ bool EditedSource::canInsertInOffset(Sou
}
if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
- SourceLocation
- DefArgLoc = SourceMgr.getImmediateExpansionRange(OrigLoc).first;
- SourceLocation
- ExpLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
- llvm::DenseMap<unsigned, SourceLocation>::iterator
- I = ExpansionToArgMap.find(ExpLoc.getRawEncoding());
- if (I != ExpansionToArgMap.end() && I->second != DefArgLoc)
- return false; // Trying to write in a macro argument input that has
- // already been written for another argument of the same macro.
+ IdentifierInfo *II;
+ SourceLocation ExpLoc;
+ deconstructMacroArgLoc(OrigLoc, ExpLoc, II);
+ auto I = ExpansionToArgMap.find(ExpLoc.getRawEncoding());
+ if (I != ExpansionToArgMap.end() &&
+ std::find(I->second.begin(), I->second.end(), II) != I->second.end()) {
+ // Trying to write in a macro argument input that has already been
+ // written by a previous commit for another expansion of the same macro
+ // argument name. For example:
+ //
+ // \code
+ // #define MAC(x) ((x)+(x))
+ // MAC(a)
+ // \endcode
+ //
+ // A commit modified the macro argument 'a' due to the first '(x)'
+ // expansion inside the macro definition, and a subsequent commit tried
+ // to modify 'a' again for the second '(x)' expansion. The edits of the
+ // second commit will be rejected.
+ return false;
+ }
}
return true;
@@ -59,11 +101,11 @@ bool EditedSource::commitInsert(SourceLo
return true;
if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
- SourceLocation
- DefArgLoc = SourceMgr.getImmediateExpansionRange(OrigLoc).first;
- SourceLocation
- ExpLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
- ExpansionToArgMap[ExpLoc.getRawEncoding()] = DefArgLoc;
+ IdentifierInfo *II;
+ SourceLocation ExpLoc;
+ deconstructMacroArgLoc(OrigLoc, ExpLoc, II);
+ if (II)
+ CurrCommitMacroArgExps.emplace_back(ExpLoc, II);
}
FileEdit &FA = FileEdits[Offs];
@@ -219,6 +261,16 @@ bool EditedSource::commit(const Commit &
if (!commit.isCommitable())
return false;
+ struct CommitRAII {
+ EditedSource &Editor;
+ CommitRAII(EditedSource &Editor) : Editor(Editor) {
+ Editor.startingCommit();
+ }
+ ~CommitRAII() {
+ Editor.finishedCommit();
+ }
+ } CommitRAII(*this);
+
for (edit::Commit::edit_iterator
I = commit.edit_begin(), E = commit.edit_end(); I != E; ++I) {
const edit::Commit::Edit &edit = *I;
Modified: cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m?rev=247462&r1=247461&r2=247462&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m (original)
+++ cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m Fri Sep 11 15:09:11 2015
@@ -88,6 +88,7 @@ typedef const struct __CFString * CFStri
#define M(x) (x)
#define PAIR(x) @#x, [NSNumber numberWithInt:(x)]
#define TWO(x) ((x), (x))
+#define TWO_SEP(x,y) ((x), (y))
@interface I {
NSArray *ivarArr;
@@ -118,6 +119,7 @@ typedef const struct __CFString * CFStri
id o = [arr objectAtIndex:2];
o = [dict objectForKey:@"key"];
o = TWO([dict objectForKey:@"key"]);
+ o = TWO_SEP([dict objectForKey:@"key"], [arr objectAtIndex:2]);
o = [NSDictionary dictionaryWithObject:[NSDictionary dictionary] forKey:@"key"];
NSMutableArray *marr = 0;
NSMutableDictionary *mdict = 0;
Modified: cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result?rev=247462&r1=247461&r2=247462&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result (original)
+++ cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result Fri Sep 11 15:09:11 2015
@@ -88,6 +88,7 @@ typedef const struct __CFString * CFStri
#define M(x) (x)
#define PAIR(x) @#x, [NSNumber numberWithInt:(x)]
#define TWO(x) ((x), (x))
+#define TWO_SEP(x,y) ((x), (y))
@interface I {
NSArray *ivarArr;
@@ -118,6 +119,7 @@ typedef const struct __CFString * CFStri
id o = arr[2];
o = dict[@"key"];
o = TWO(dict[@"key"]);
+ o = TWO_SEP(dict[@"key"], arr[2]);
o = @{@"key": @{}};
NSMutableArray *marr = 0;
NSMutableDictionary *mdict = 0;
More information about the cfe-commits
mailing list