forked from OSchip/llvm-project
When associating file ranges of macro arguments with their
macro expansion ranges, make sure to check all the FileID entries that are contained in the spelling range of the expansion for the macro argument. Fixes rdar://12537982 llvm-svn: 166359
This commit is contained in:
parent
03c20e83b8
commit
73ccdb9c15
|
@ -1556,7 +1556,11 @@ private:
|
|||
getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
|
||||
unsigned Offset) const;
|
||||
void computeMacroArgsCache(MacroArgsMap *&MacroArgsCache, FileID FID) const;
|
||||
|
||||
void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache,
|
||||
FileID FID,
|
||||
SourceLocation SpellLoc,
|
||||
SourceLocation ExpansionLoc,
|
||||
unsigned ExpansionLength) const;
|
||||
friend class ASTReader;
|
||||
friend class ASTWriter;
|
||||
};
|
||||
|
|
|
@ -1705,22 +1705,68 @@ void SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr,
|
|||
if (!ExpInfo.isMacroArgExpansion())
|
||||
continue;
|
||||
|
||||
SourceLocation SpellLoc = ExpInfo.getSpellingLoc();
|
||||
while (!SpellLoc.isFileID()) {
|
||||
std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(SpellLoc);
|
||||
const ExpansionInfo &Info = getSLocEntry(LocInfo.first).getExpansion();
|
||||
if (!Info.isMacroArgExpansion())
|
||||
break;
|
||||
SpellLoc = Info.getSpellingLoc().getLocWithOffset(LocInfo.second);
|
||||
associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
|
||||
ExpInfo.getSpellingLoc(),
|
||||
SourceLocation::getMacroLoc(Entry.getOffset()),
|
||||
getFileIDSize(FileID::get(ID)));
|
||||
}
|
||||
if (!SpellLoc.isFileID())
|
||||
continue;
|
||||
}
|
||||
|
||||
void SourceManager::associateFileChunkWithMacroArgExp(
|
||||
MacroArgsMap &MacroArgsCache,
|
||||
FileID FID,
|
||||
SourceLocation SpellLoc,
|
||||
SourceLocation ExpansionLoc,
|
||||
unsigned ExpansionLength) const {
|
||||
if (!SpellLoc.isFileID()) {
|
||||
unsigned SpellBeginOffs = SpellLoc.getOffset();
|
||||
unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength;
|
||||
|
||||
// The spelling range for this macro argument expansion can span multiple
|
||||
// consecutive FileID entries. Go through each entry contained in the
|
||||
// spelling range and if one is itself a macro argument expansion, recurse
|
||||
// and associate the file chunk that it represents.
|
||||
|
||||
FileID SpellFID; // Current FileID in the spelling range.
|
||||
unsigned SpellRelativeOffs;
|
||||
llvm::tie(SpellFID, SpellRelativeOffs) = getDecomposedLoc(SpellLoc);
|
||||
while (1) {
|
||||
const SLocEntry &Entry = getSLocEntry(SpellFID);
|
||||
unsigned SpellFIDBeginOffs = Entry.getOffset();
|
||||
unsigned SpellFIDSize = getFileIDSize(SpellFID);
|
||||
unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize;
|
||||
const ExpansionInfo &Info = Entry.getExpansion();
|
||||
if (Info.isMacroArgExpansion()) {
|
||||
unsigned CurrSpellLength;
|
||||
if (SpellFIDEndOffs < SpellEndOffs)
|
||||
CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
|
||||
else
|
||||
CurrSpellLength = ExpansionLength;
|
||||
associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
|
||||
Info.getSpellingLoc().getLocWithOffset(SpellRelativeOffs),
|
||||
ExpansionLoc, CurrSpellLength);
|
||||
}
|
||||
|
||||
if (SpellFIDEndOffs >= SpellEndOffs)
|
||||
return; // we covered all FileID entries in the spelling range.
|
||||
|
||||
// Move to the next FileID entry in the spelling range.
|
||||
unsigned advance = SpellFIDSize - SpellRelativeOffs + 1;
|
||||
ExpansionLoc = ExpansionLoc.getLocWithOffset(advance);
|
||||
ExpansionLength -= advance;
|
||||
++SpellFID.ID;
|
||||
SpellRelativeOffs = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
assert(SpellLoc.isFileID());
|
||||
|
||||
unsigned BeginOffs;
|
||||
if (!isInFileID(SpellLoc, FID, &BeginOffs))
|
||||
continue;
|
||||
return;
|
||||
|
||||
unsigned EndOffs = BeginOffs + getFileIDSize(FileID::get(ID));
|
||||
unsigned EndOffs = BeginOffs + ExpansionLength;
|
||||
|
||||
// Add a new chunk for this macro argument. A previous macro argument chunk
|
||||
// may have been lexed again, so e.g. if the map is
|
||||
|
@ -1742,9 +1788,8 @@ void SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr,
|
|||
MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
|
||||
--I;
|
||||
SourceLocation EndOffsMappedLoc = I->second;
|
||||
MacroArgsCache[BeginOffs] = SourceLocation::getMacroLoc(Entry.getOffset());
|
||||
MacroArgsCache[BeginOffs] = ExpansionLoc;
|
||||
MacroArgsCache[EndOffs] = EndOffsMappedLoc;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief If \arg Loc points inside a function macro argument, the returned
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
+(void)meth;
|
||||
@end
|
||||
|
||||
#define MACRO2(x) x
|
||||
#define MACRO(x) MACRO2(x)
|
||||
#define MACRO2(x) (x)
|
||||
#define MACRO(x) MACRO2((x))
|
||||
|
||||
void test() {
|
||||
MACRO([MyClass meth]);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Test without PCH
|
||||
// RUN: c-index-test -cursor-at=%S/get-cursor-macro-args.h:9:12 \
|
||||
// RUN: -cursor-at=%S/get-cursor-macro-args.h:9:21 \
|
||||
// RUN: -cursor-at=%S/get-cursor-macro-args.h:9:9 \
|
||||
// RUN: -cursor-at=%S/get-cursor-macro-args.h:9:22 \
|
||||
// RUN: -cursor-at=%S/get-cursor-macro-args.h:15:12 \
|
||||
// RUN: -cursor-at=%S/get-cursor-macro-args.h:15:20 \
|
||||
// RUN: %s -include %S/get-cursor-macro-args.h | FileCheck %s
|
||||
|
@ -9,6 +11,8 @@
|
|||
// RUN: c-index-test -write-pch %t.pch -x objective-c-header %S/get-cursor-macro-args.h
|
||||
// RUN: c-index-test -cursor-at=%S/get-cursor-macro-args.h:9:12 \
|
||||
// RUN: -cursor-at=%S/get-cursor-macro-args.h:9:21 \
|
||||
// RUN: -cursor-at=%S/get-cursor-macro-args.h:9:9 \
|
||||
// RUN: -cursor-at=%S/get-cursor-macro-args.h:9:22 \
|
||||
// RUN: -cursor-at=%S/get-cursor-macro-args.h:15:12 \
|
||||
// RUN: -cursor-at=%S/get-cursor-macro-args.h:15:20 \
|
||||
// RUN: %s -include-pch %t.pch | FileCheck %s
|
||||
|
@ -16,4 +20,6 @@
|
|||
// CHECK: ObjCClassRef=MyClass:1:12
|
||||
// CHECK-NEXT: ObjCMessageExpr=meth:2:8
|
||||
// CHECK-NEXT: ObjCMessageExpr=meth:2:8
|
||||
// CHECK-NEXT: ObjCMessageExpr=meth:2:8
|
||||
// CHECK-NEXT: ObjCMessageExpr=meth:2:8
|
||||
// CHECK-NEXT: ObjCClassRef=MyClass:1:12
|
||||
|
|
Loading…
Reference in New Issue