1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-21 21:52:10 +02:00

Bug 568957 - Header indexed with missing significant macros on multiple

headers with pragma once syntax

Change-Id: Iada2129ec7bf4f239ffdaa13ca3e33e322aa1025
Signed-off-by: Michael Uhl <Michael.Uhl@NashTech.Com>
This commit is contained in:
Michael Uhl 2020-12-21 10:14:20 +01:00 committed by Jeff Johnston
parent 27b9002fbc
commit 28589d32a3
3 changed files with 203 additions and 1 deletions

View file

@ -14,7 +14,11 @@
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
import static org.eclipse.cdt.core.testplugin.util.TestSourceReader.createFile;
import java.io.ByteArrayInputStream;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
@ -25,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.index.IndexLocationFactory;
@ -36,11 +41,13 @@ import org.eclipse.cdt.core.testplugin.TestScannerProvider;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.junit.Assert;
import junit.framework.TestSuite;
@ -642,6 +649,143 @@ public class IndexIncludeTest extends IndexTestBase {
}
}
// #pragma once
// #ifdef ABC
// int x = 5;
// #endif
// #pragma once
// #include "b.hpp"
// #pragma once
// #include "b.hpp"
// #include "a1.hpp"
// #include "a2.hpp"
public void testSignificantMacrosWithPragmeOnceSemantic() throws Exception {
waitForIndexer();
IProject prj = fProject.getProject();
TestScannerProvider.sIncludes = new String[] { prj.getLocation().toOSString() };
CharSequence[] contents = getContentsForTest(5);
IFile b = createFile(prj, "b.hpp", contents[0].toString());
IFile a1 = createFile(prj, "a1.hpp", contents[1].toString());
IFile a2 = createFile(prj, "a2.hpp", contents[2].toString());
final IFile main = createFile(prj, "UltimateTest.cpp", contents[3].toString());
waitUntilFileIsIndexed(fIndex, b);
waitUntilFileIsIndexed(fIndex, a1);
waitUntilFileIsIndexed(fIndex, a2);
waitUntilFileIsIndexed(fIndex, main);
fIndex.acquireReadLock();
try {
IIndexFile[] indexFiles = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID,
IndexLocationFactory.getWorkspaceIFL(main));
IIndexFile ultimateTestCppIdx = indexFiles[0];
IIndexFile includes[] = new IIndexFile[3];
includes[0] = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(b))[0];
includes[1] = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(a1))[0];
includes[2] = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(a2))[0];
for (int i = 0; i < includes.length; i++) {
IIndexFile include = includes[i];
outputUnresolvedIncludes(fIndex, include.getLocation(), ultimateTestCppIdx, new HashSet<IIndexFile>());
}
} finally {
fIndex.releaseReadLock();
}
}
// #pragma once
// #ifdef ABC
// int x = 5;
// #endif
// #pragma once
// #include "b.hpp"
// #pragma once
// #include "b.hpp"
// #pragma once
// #include "b.hpp"
// #pragma once
// #include "b.hpp"
// #include "a1.hpp"
// #include "a2.hpp"
// #include "a3.hpp"
// #include "a4.hpp"
public void testSignificantMacrosWithPragmeOnceFromIdxSemantic() throws Exception {
waitForIndexer();
IProject prj = fProject.getProject();
TestScannerProvider.sIncludes = new String[] { prj.getLocation().toOSString() };
CharSequence[] contents = getContentsForTest(7);
IFile b = createFile(prj, "b.hpp", contents[0].toString());
IFile a1 = createFile(prj, "a1.hpp", contents[1].toString());
IFile a2 = createFile(prj, "a2.hpp", contents[2].toString());
IFile a3 = createFile(prj, "a3.hpp", contents[3].toString());
IFile a4 = createFile(prj, "a4.hpp", contents[4].toString());
final IFile s1 = createFile(prj, "s1.cpp", contents[5].toString());
final IFile s2 = createFile(prj, "s2.cpp", contents[6].toString());
waitUntilFileIsIndexed(fIndex, b);
waitUntilFileIsIndexed(fIndex, a1);
waitUntilFileIsIndexed(fIndex, a2);
waitUntilFileIsIndexed(fIndex, a3);
waitUntilFileIsIndexed(fIndex, a4);
waitUntilFileIsIndexed(fIndex, s1);
waitUntilFileIsIndexed(fIndex, s2);
fIndex.acquireReadLock();
try {
IIndexFile[] indexFiles = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID,
IndexLocationFactory.getWorkspaceIFL(s1));
IIndexFile ultimateTestCppIdx = indexFiles[0];
IIndexFile includes[] = new IIndexFile[5];
includes[0] = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(b))[0];
includes[1] = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(a1))[0];
includes[2] = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(a2))[0];
includes[3] = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(a3))[0];
includes[4] = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(a4))[0];
for (int i = 0; i < includes.length; i++) {
IIndexFile include = includes[i];
outputUnresolvedIncludes(fIndex, include.getLocation(), ultimateTestCppIdx, new HashSet<IIndexFile>());
}
} finally {
fIndex.releaseReadLock();
}
}
private void outputUnresolvedIncludes(IIndex index, IIndexFileLocation ifl, IIndexFile ifile,
Set<IIndexFile> handled) throws CoreException {
if (ifile == null) {
Assert.fail(ifl.getURI() + " is not indexed");
} else if (handled.add(ifile)) {
IIndexInclude[] includes = ifile.getIncludes();
for (IIndexInclude inc : includes) {
if (inc.isActive()) {
if (inc.isResolved()) {
IIndexFile next = index.resolveInclude(inc);
outputUnresolvedIncludes(index, inc.getIncludesLocation(), next, handled);
} else {
Assert.fail("Unresolved inclusion: " + inc.getFullName() + " in file "
+ inc.getIncludedByLocation().getURI());
}
}
}
}
}
private void standardCheckUpdateIncludes(IFile header, IFile s1, String tag) throws Exception {
fIndex.acquireReadLock();
try {

View file

@ -185,7 +185,13 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final InternalFileContent fc;
IFileNomination once = fFileContentProvider.isIncludedWithPragmaOnceSemantics(path);
if (once != null) {
fc = new InternalFileContent(path, InclusionKind.SKIP_FILE);
ISignificantMacros significantMacros = ISignificantMacros.NONE;
try {
significantMacros = once.getSignificantMacros();
} catch (CoreException e) {
e.printStackTrace();
}
fc = new InternalFileContent(path, InclusionKind.SKIP_PRAGMA_ONCE_FILE, significantMacros);
} else {
fc = fFileContentProvider.getContentForInclusion(path, fMacroDictionaryFacade);
}
@ -1790,11 +1796,19 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
case SKIP_FILE:
// Already included or fast parsing mode.
break;
case SKIP_PRAGMA_ONCE_FILE:
fCurrentContext.addSignificantMacros(fi.getSignificantMacros());
break;
}
if (stmt == null) {
// Found in index or skipped.
stmt = fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1], condEndOffset,
headerName, path, userInclude, active, isHeuristic, nominationDelegate);
if (fi.getKind() == InclusionKind.SKIP_PRAGMA_ONCE_FILE) {
stmt.setSignificantMacros(fi.getSignificantMacros());
stmt.setPragamOnceSemantics(true);
}
}
// In a pragma once context store loaded versions of this non-pragma-once include
if (pragmaOnceContext && loadedVerisons != null && !loadedVerisons.isEmpty()) {
@ -1812,6 +1826,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
for (FileVersion version : fi.getNonPragmaOnceVersions()) {
fFileContentProvider.addLoadedVersions(version.fPath, Integer.MAX_VALUE, version.fSigMacros);
}
fLocationMap.skippedFile(fLocationMap.getSequenceNumberForOffset(offset), fi);
}

View file

@ -32,6 +32,11 @@ public class InternalFileContent extends FileContent {
* Instruct the preprocessor to skip this inclusion.
*/
SKIP_FILE,
/**
* Instruct the preprocessor to skip this inclusion because it has pragma
* once semantic and has already been include for current translation unit.
*/
SKIP_PRAGMA_ONCE_FILE,
/**
* The file and its dependents are indexed, required information is read
* from there.
@ -67,6 +72,7 @@ public class InternalFileContent extends FileContent {
private final long fTimestamp;
private final long fFileSize;
private final long fReadTime;
private final ISignificantMacros fSignificantMacros;
/**
* For skipping include files.
@ -88,6 +94,33 @@ public class InternalFileContent extends FileContent {
fTimestamp = NULL_TIMESTAMP;
fFileSize = NULL_FILE_SIZE;
fReadTime = 0;
fSignificantMacros = null;
}
/**
* For skipping include files that have pragma once semantic and have already been include
* in the translation unit. Only the significant macros need to be forwarded to includer.
* @param fileLocation the location of the file.
* @param kind must be {@link InclusionKind#SKIP_FILE}.
* @param significantMacros The significant macros this file.
* @throws IllegalArgumentException if fileLocation is <code>null</code> or the kind value is illegal for
* this constructor.
*/
public InternalFileContent(String fileLocation, InclusionKind kind, ISignificantMacros significantMacros)
throws IllegalArgumentException {
if (fileLocation == null || kind != InclusionKind.SKIP_PRAGMA_ONCE_FILE) {
throw new IllegalArgumentException();
}
fKind = kind;
fFileLocation = fileLocation;
fMacroDefinitions = null;
fUsingDirectives = null;
fSource = null;
fNonPragmaOnceFiles = null;
fTimestamp = NULL_TIMESTAMP;
fFileSize = NULL_FILE_SIZE;
fReadTime = 0;
fSignificantMacros = significantMacros;
}
/**
@ -111,6 +144,7 @@ public class InternalFileContent extends FileContent {
fTimestamp = timestamp;
fFileSize = fileSize;
fReadTime = fileReadTime;
fSignificantMacros = null;
}
/**
@ -133,6 +167,7 @@ public class InternalFileContent extends FileContent {
fTimestamp = NULL_TIMESTAMP;
fFileSize = NULL_FILE_SIZE;
fReadTime = 0;
fSignificantMacros = null;
}
/**
@ -154,6 +189,7 @@ public class InternalFileContent extends FileContent {
fTimestamp = NULL_TIMESTAMP;
fFileSize = NULL_FILE_SIZE;
fReadTime = 0;
fSignificantMacros = null;
}
/**
@ -274,4 +310,11 @@ public class InternalFileContent extends FileContent {
public String toString() {
return getSource().toString();
}
public ISignificantMacros getSignificantMacros() {
if (fKind != InclusionKind.SKIP_PRAGMA_ONCE_FILE) {
throw new IllegalArgumentException();
}
return fSignificantMacros;
}
}