r.stahl created this revision.
r.stahl added reviewers: a.sidorin, klimek, martong.
Herald added subscribers: cfe-commits, rnkovacs.
Implement full import of macro expansion info with spelling and expansion
locations.
Repository:
rC Clang
https://reviews.llvm.org/D47698
Files:
lib/AST/ASTImporter.cpp
unittests/AST/ASTImporterTest.cpp
Index: unittests/AST/ASTImporterTest.cpp
===================================================================
--- unittests/AST/ASTImporterTest.cpp
+++ unittests/AST/ASTImporterTest.cpp
@@ -1518,6 +1518,50 @@
ToTU, cxxRecordDecl(unless(isImplicit()))));
}
+static void CompareSourceLocs(SourceLocation Loc1, SourceLocation Loc2,
+ SourceManager &SM1, SourceManager &SM2) {
+ EXPECT_EQ(SM1.getExpansionLineNumber(Loc1), SM2.getExpansionLineNumber(Loc2));
+ EXPECT_EQ(SM1.getExpansionColumnNumber(Loc1),
+ SM2.getExpansionColumnNumber(Loc2));
+ EXPECT_EQ(SM1.getSpellingLineNumber(Loc1), SM2.getSpellingLineNumber(Loc2));
+ EXPECT_EQ(SM1.getSpellingColumnNumber(Loc1),
+ SM2.getSpellingColumnNumber(Loc2));
+}
+static void CompareSourceRanges(SourceRange Range1, SourceRange Range2,
+ SourceManager &SM1, SourceManager &SM2) {
+ CompareSourceLocs(Range1.getBegin(), Range2.getBegin(), SM1, SM2);
+ CompareSourceLocs(Range1.getEnd(), Range2.getEnd(), SM1, SM2);
+}
+TEST_P(ASTImporterTestBase, ImportSourceLocs) {
+ Decl *FromTU = getTuDecl(
+ R"(
+ #define MFOO(arg) arg = arg + 1
+
+ void foo() {
+ int a = 5;
+ MFOO(a);
+ }
+ )",
+ Lang_CXX);
+ auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
+ auto ToD = Import(FromD, Lang_CXX);
+
+ auto ToLHS = LastDeclMatcher<DeclRefExpr>().match(ToD, declRefExpr());
+ auto FromLHS = LastDeclMatcher<DeclRefExpr>().match(FromTU, declRefExpr());
+ auto ToRHS = LastDeclMatcher<IntegerLiteral>().match(ToD, integerLiteral());
+ auto FromRHS =
+ LastDeclMatcher<IntegerLiteral>().match(FromTU, integerLiteral());
+
+ SourceManager &ToSM = ToAST->getASTContext().getSourceManager();
+ SourceManager &FromSM = FromD->getASTContext().getSourceManager();
+ CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM,
+ FromSM);
+ CompareSourceRanges(ToLHS->getSourceRange(), FromLHS->getSourceRange(), ToSM,
+ FromSM);
+ CompareSourceRanges(ToRHS->getSourceRange(), FromRHS->getSourceRange(), ToSM,
+ FromSM);
+}
+
TEST_P(
ASTImporterTestBase,
ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition)
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -52,6 +52,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Lex/Lexer.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
@@ -7029,61 +7030,70 @@
return {};
SourceManager &FromSM = FromContext.getSourceManager();
-
- // For now, map everything down to its file location, so that we
- // don't have to import macro expansions.
- // FIXME: Import macro expansions!
- FromLoc = FromSM.getFileLoc(FromLoc);
+
std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
- SourceManager &ToSM = ToContext.getSourceManager();
FileID ToFileID = Import(Decomposed.first);
if (ToFileID.isInvalid())
return {};
- SourceLocation ret = ToSM.getLocForStartOfFile(ToFileID)
- .getLocWithOffset(Decomposed.second);
- return ret;
+ SourceManager &ToSM = ToContext.getSourceManager();
+ return ToSM.getComposedLoc(ToFileID, Decomposed.second);
}
SourceRange ASTImporter::Import(SourceRange FromRange) {
return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
}
FileID ASTImporter::Import(FileID FromID) {
- llvm::DenseMap<FileID, FileID>::iterator Pos
- = ImportedFileIDs.find(FromID);
+ llvm::DenseMap<FileID, FileID>::iterator Pos = ImportedFileIDs.find(FromID);
if (Pos != ImportedFileIDs.end())
return Pos->second;
-
+
SourceManager &FromSM = FromContext.getSourceManager();
SourceManager &ToSM = ToContext.getSourceManager();
const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
- assert(FromSLoc.isFile() && "Cannot handle macro expansions yet");
-
- // Include location of this file.
- SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
-
+
// Map the FileID for to the "to" source manager.
FileID ToID;
- const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
- if (Cache->OrigEntry && Cache->OrigEntry->getDir()) {
- // FIXME: We probably want to use getVirtualFile(), so we don't hit the
- // disk again
- // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
- // than mmap the files several times.
- const FileEntry *Entry = ToFileManager.getFile(Cache->OrigEntry->getName());
- if (!Entry)
- return {};
- ToID = ToSM.createFileID(Entry, ToIncludeLoc,
- FromSLoc.getFile().getFileCharacteristic());
+ if (FromSLoc.isExpansion()) {
+ const SrcMgr::ExpansionInfo &FromEx = FromSLoc.getExpansion();
+ SourceLocation ToSpLoc = Import(FromEx.getSpellingLoc());
+ SourceLocation ToExLocS = Import(FromEx.getExpansionLocStart());
+ SourceLocation ToExLocE = Import(FromEx.getExpansionLocEnd());
+ unsigned TokenLen = FromSM.getFileIDSize(FromID);
+ if (FromEx.isMacroArgExpansion()) {
+ auto MLoc = ToSM.createMacroArgExpansionLoc(ToSpLoc, ToExLocS, TokenLen);
+ ToID = ToSM.getFileID(MLoc);
+ } else {
+ auto MLoc = ToSM.createExpansionLoc(ToSpLoc, ToExLocS, ToExLocE, TokenLen,
+ FromEx.isExpansionTokenRange());
+ ToID = ToSM.getFileID(MLoc);
+ }
} else {
- // FIXME: We want to re-use the existing MemoryBuffer!
- const llvm::MemoryBuffer *
- FromBuf = Cache->getBuffer(FromContext.getDiagnostics(), FromSM);
- std::unique_ptr<llvm::MemoryBuffer> ToBuf
- = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
- FromBuf->getBufferIdentifier());
- ToID = ToSM.createFileID(std::move(ToBuf),
- FromSLoc.getFile().getFileCharacteristic());
+ // Include location of this file.
+ SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
+
+ const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
+ if (Cache->OrigEntry && Cache->OrigEntry->getDir()) {
+ // FIXME: We probably want to use getVirtualFile(), so we don't hit the
+ // disk again
+ // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
+ // than mmap the files several times.
+ const FileEntry *Entry =
+ ToFileManager.getFile(Cache->OrigEntry->getName());
+ if (!Entry)
+ return {};
+ ToID = ToSM.createFileID(Entry, ToIncludeLoc,
+ FromSLoc.getFile().getFileCharacteristic());
+ } else {
+ // FIXME: We want to re-use the existing MemoryBuffer!
+ const llvm::MemoryBuffer *FromBuf =
+ Cache->getBuffer(FromContext.getDiagnostics(), FromSM);
+ std::unique_ptr<llvm::MemoryBuffer> ToBuf =
+ llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
+ FromBuf->getBufferIdentifier());
+ ToID = ToSM.createFileID(std::move(ToBuf),
+ FromSLoc.getFile().getFileCharacteristic());
+ }
}
ImportedFileIDs[FromID] = ToID;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits