diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java
index 0d17bbe0c43..e9331d9361f 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java
@@ -2278,4 +2278,42 @@ public class IndexBugsTests extends BaseTestCase {
index.releaseReadLock();
}
}
+
+ public void testUpdateForContentTypeChange_283080() throws Exception {
+ IIndexBinding[] r;
+
+ final IProject prj = fCProject.getProject();
+ IFile file= TestSourceReader.createFile(prj, "a.cpp", "// \u0110 \n int a;");
+ file.setCharset("US-ASCII", new NullProgressMonitor());
+ waitForIndexer(fCProject);
+
+ final IIndex index= CCorePlugin.getIndexManager().getIndex(fCProject);
+ int offset1= 0;
+ index.acquireReadLock();
+ try {
+ r = index.findBindings("a".toCharArray(), IndexFilter.ALL_DECLARED, null);
+ assertEquals(1, r.length);
+ IIndexName[] defs = index.findDefinitions(r[0]);
+ assertEquals(1, defs.length);
+ offset1= defs[0].getNodeOffset();
+ } finally {
+ index.releaseReadLock();
+ }
+
+ file.setCharset("UTF-8", new NullProgressMonitor());
+ waitForIndexer(fCProject);
+ int offset2= 0;
+ index.acquireReadLock();
+ try {
+ r = index.findBindings("a".toCharArray(), IndexFilter.ALL_DECLARED, null);
+ assertEquals(1, r.length);
+ IIndexName[] defs = index.findDefinitions(r[0]);
+ assertEquals(1, defs.length);
+ offset1= defs[0].getNodeOffset();
+ } finally {
+ index.releaseReadLock();
+ }
+
+ assertTrue(offset1 != offset2);
+ }
}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java
index 353a20dc6a8..cb6f18fc722 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java
@@ -76,6 +76,14 @@ public interface IIndexFile {
*/
int getScannerConfigurationHashcode() throws CoreException;
+ /**
+ * Returns the hash-code of the file encoding that was used to parse the file.
+ * 0
will be returned in case the hash-code is unknown.
+ * @return the hash-code of the file encoding or 0
.
+ * @since 5.3
+ */
+ int getEncodingHashcode() throws CoreException;
+
/**
* Find all names within the given range.
*/
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/FileContent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/FileContent.java
index bc9a4d20953..d386f644ea7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/FileContent.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/FileContent.java
@@ -83,11 +83,16 @@ public abstract class FileContent {
return InternalParserUtil.createWorkspaceFileContent(file);
}
+ public static FileContent createForExternalFileLocation(String fileLocation) {
+ return createForExternalFileLocation(fileLocation, InternalParserUtil.SYSTEM_DEFAULT_ENCODING);
+ }
+
/**
* Creates a file content object for a file location that is not part of the workspace
+ * @since 5.3
*/
- public static FileContent createForExternalFileLocation(String fileLocation) {
- return InternalParserUtil.createExternalFileContent(fileLocation);
+ public static FileContent createForExternalFileLocation(String fileLocation, String encoding) {
+ return InternalParserUtil.createExternalFileContent(fileLocation, encoding);
}
/**
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java
index 2a74bfc873a..887133feb52 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java
@@ -40,6 +40,12 @@ public interface IIndexFragmentFile extends IIndexFile {
*/
void setScannerConfigurationHashcode(int hashcode) throws CoreException;
+ /**
+ * Sets the hash-code of the file encoding.
+ * @param hashcode a hash-code or 0
if it is unknown.
+ */
+ void setEncodingHashcode(int hashcode) throws CoreException;
+
/**
* Returns whether this file contains content in its
* associated fragment. Files without content are inserted to track includes.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java
index fc9726992c9..a2d3c69ec45 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java
@@ -17,10 +17,10 @@ import java.util.HashMap;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.model.AbstractLanguage;
import org.eclipse.cdt.core.model.ILanguage;
-import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.FileContent;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
+import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
import org.eclipse.cdt.internal.core.pdom.IndexerInputAdapter;
import org.eclipse.cdt.internal.core.pdom.indexer.FileExistsCache;
import org.eclipse.core.filesystem.URIUtil;
@@ -51,6 +51,16 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter {
return new File(URIUtil.toPath(location.getURI()).toOSString()).lastModified();
}
+
+ @Override
+ public String getEncoding(IIndexFileLocation ifl) {
+ String encoding= getFileEncoding(getASTPath(ifl));
+ if (encoding == null)
+ return InternalParserUtil.SYSTEM_DEFAULT_ENCODING;
+
+ return encoding;
+ }
+
@Override
public boolean isSourceUnit(Object tu) {
return isValidSourceUnitName((String) tu);
@@ -130,24 +140,23 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter {
@Override
public FileContent getCodeReader(Object tu) {
- try {
- String stu = (String) tu;
- String fileEncoding = null;
- // query file's encoding, if we find it and use it to create CodeReader
- FileEncodingRegistry fileEncodingRegistry = fIndexer.getFileEncodingRegistry();
- if(fileEncodingRegistry != null){
- fileEncoding = fileEncodingRegistry.getFileEncoding(stu);
- }
+ String stu = (String) tu;
+ String fileEncoding = getFileEncoding(stu);
- if (fileEncoding != null) {
- // TODO this is bad
- return FileContent.adapt(new CodeReader(stu, fileEncoding));
- } else {
- return FileContent.createForExternalFileLocation((String) tu);
- }
- } catch (IOException e) {
+ return FileContent.createForExternalFileLocation(stu, fileEncoding);
+ }
+
+ public String getFileEncoding(String stu) {
+ String fileEncoding = null;
+ // query file's encoding, if we find it and use it to create CodeReader
+ FileEncodingRegistry fileEncodingRegistry = fIndexer.getFileEncodingRegistry();
+ if(fileEncodingRegistry != null){
+ fileEncoding = fileEncodingRegistry.getFileEncoding(stu);
}
- return null;
+ if (fileEncoding == null)
+ return InternalParserUtil.SYSTEM_DEFAULT_ENCODING;
+
+ return fileEncoding;
}
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java
index 6073ffccee8..23ef5a39786 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java
@@ -36,7 +36,7 @@ import org.eclipse.core.runtime.Path;
* Utility for creating code readers
*/
public class InternalParserUtil extends ParserFactory {
- private static final String SYSTEM_DEFAULT_ENCODING = System.getProperty("file.encoding"); //$NON-NLS-1$
+ public static final String SYSTEM_DEFAULT_ENCODING = System.getProperty("file.encoding"); //$NON-NLS-1$
/**
* Normalizes the path by using the location of the file, if possible.
@@ -133,7 +133,7 @@ public class InternalParserUtil extends ParserFactory {
if (res instanceof IFile)
return createWorkspaceFileContent((IFile) res);
}
- return createExternalFileContent(ifl.getURI().getPath());
+ return createExternalFileContent(ifl.getURI().getPath(), SYSTEM_DEFAULT_ENCODING);
}
public static InternalFileContent createWorkspaceFileContent(IFile file) {
@@ -170,7 +170,7 @@ public class InternalParserUtil extends ParserFactory {
* Creates a code reader for an external location, normalizing path to
* canonical path.
*/
- public static InternalFileContent createExternalFileContent(String externalLocation) {
+ public static InternalFileContent createExternalFileContent(String externalLocation, String encoding) {
File includeFile = new File(externalLocation);
if (includeFile.isFile()) {
// Use the canonical path so that in case of non-case-sensitive OSs
@@ -185,7 +185,7 @@ public class InternalParserUtil extends ParserFactory {
return null;
}
try {
- return createFileContent(path, SYSTEM_DEFAULT_ENCODING, in);
+ return createFileContent(path, encoding, in);
} finally {
try {
in.close();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
index 99ea7204c1d..44caaddfd82 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
@@ -445,13 +445,16 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
private boolean isModified(boolean checkTimestamps, boolean checkFileContentsHash, IIndexFileLocation ifl,
Object tu, IIndexFragmentFile file) throws CoreException {
- boolean timestampDifferent = checkTimestamps && fResolver.getLastModified(ifl) != file.getTimestamp();
- if (timestampDifferent) {
- if (checkFileContentsHash && computeFileContentsHash(tu) == file.getContentsHash()) {
- return false;
+ if (checkTimestamps) {
+ if (fResolver.getLastModified(ifl) != file.getTimestamp() ||
+ fResolver.getEncoding(ifl).hashCode() != file.getEncodingHashcode()) {
+ if (checkFileContentsHash && computeFileContentsHash(tu) == file.getContentsHash()) {
+ return false;
+ }
+ return true;
}
}
- return timestampDifferent;
+ return false;
}
private void requestUpdate(int linkageID, IIndexFileLocation ifl, IIndexFragmentFile ifile) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java
index 62f6ccd28e7..e83b16a52db 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java
@@ -70,4 +70,8 @@ public abstract class IndexerInputAdapter extends ASTFilePathResolver {
*/
public abstract FileContent getCodeReader(Object tu);
+ /**
+ * Returns the encoding for the file.
+ */
+ public abstract String getEncoding(IIndexFileLocation ifl);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index 88036473e75..59c3bd1c169 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -193,11 +193,14 @@ public class PDOM extends PlatformObject implements IPDOM {
* 95.0 - parameter packs, bug 294730.
* 96.0 - storing pack expansions in the template parameter map, bug 294730.
* 97.0 - storing file contents hash in PDOMFile, bug 302083.
- * 98.0 - strongly typed enums, bug 305975.
+ * #98.0# - strongly typed enums, bug 305975. <>
+ *
+ * CDT 8.0 development (versions not supported on the 7.0.x branch)
+ * 110.0 - update index on encoding change, bug 317435.
*/
- private static final int MIN_SUPPORTED_VERSION= version(98, 0);
- private static final int MAX_SUPPORTED_VERSION= version(98, Short.MAX_VALUE);
- private static final int DEFAULT_VERSION = version(98, 0);
+ private static final int MIN_SUPPORTED_VERSION= version(110, 0);
+ private static final int MAX_SUPPORTED_VERSION= version(110, Short.MAX_VALUE);
+ private static final int DEFAULT_VERSION = version(110, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java
index b51b6bbb483..fa6382de502 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java
@@ -38,6 +38,7 @@ import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.ITypedef;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
@@ -45,7 +46,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.parser.IProblem;
@@ -461,7 +461,6 @@ abstract public class PDOMWriter {
YieldableIndexLock lock) throws CoreException, InterruptedException {
Set clearedContexts= Collections.emptySet();
IIndexFragmentFile file;
- long timestamp = fResolver.getLastModified(location);
// We create a temporary PDOMFile with zero timestamp, add names to it, then replace contents
// of the old file from the temporary one, then delete the temporary file. The write lock on
// the index can be yielded between adding names to the temporary file, if another thread
@@ -503,7 +502,8 @@ abstract public class PDOMWriter {
}
index.setFileContent(file, linkageID, includeInfos, macros, names, fResolver, lock);
}
- file.setTimestamp(timestamp);
+ file.setTimestamp(fResolver.getLastModified(location));
+ file.setEncodingHashcode(fResolver.getEncoding(location).hashCode());
file.setContentsHash(fileContentsHash);
file = index.commitUncommittedFile();
} finally {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
index b79e64f1f5b..bdd985b3cf6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
@@ -40,9 +40,9 @@ import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
+import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
-import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
@@ -73,10 +73,11 @@ public class PDOMFile implements IIndexFragmentFile {
private static final int TIME_STAMP = 24;
private static final int CONTENT_HASH= 32;
private static final int SCANNER_CONFIG_HASH= 40;
- private static final int LAST_USING_DIRECTIVE= 44;
- private static final int FIRST_MACRO_REFERENCE= 48;
+ private static final int ENCODING_HASH= 44;
+ private static final int LAST_USING_DIRECTIVE= 48;
+ private static final int FIRST_MACRO_REFERENCE= 52;
- private static final int RECORD_SIZE= 52;
+ private static final int RECORD_SIZE= 56;
public static class Comparator implements IBTreeComparator {
private Database db;
@@ -224,6 +225,7 @@ public class PDOMFile implements IIndexFragmentFile {
}
setTimestamp(sourceFile.getTimestamp());
+ setEncodingHashcode(sourceFile.getEncodingHashcode());
setContentsHash(sourceFile.getContentsHash());
setScannerConfigurationHashcode(sourceFile.getScannerConfigurationHashcode());
@@ -293,6 +295,16 @@ public class PDOMFile implements IIndexFragmentFile {
db.putInt(record + SCANNER_CONFIG_HASH, hashcode);
}
+ public int getEncodingHashcode() throws CoreException {
+ Database db = fLinkage.getDB();
+ return db.getInt(record + ENCODING_HASH);
+ }
+
+ public void setEncodingHashcode(int hashcode) throws CoreException {
+ Database db= fLinkage.getDB();
+ db.putInt(record + ENCODING_HASH, hashcode);
+ }
+
private PDOMName getFirstName() throws CoreException {
long namerec = fLinkage.getDB().getRecPtr(record + FIRST_NAME);
return namerec != 0 ? new PDOMName(fLinkage, namerec) : null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java
index 94d4f16165e..142bb47444e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java
@@ -28,8 +28,10 @@ import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.core.parser.FileContent;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ScannerInfo;
+import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
import org.eclipse.cdt.internal.core.pdom.IndexerInputAdapter;
import org.eclipse.cdt.internal.core.resources.PathCanonicalizationStrategy;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
@@ -172,6 +174,21 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
return 0;
}
+ @Override
+ public String getEncoding(IIndexFileLocation ifl) {
+ String fullPath= ifl.getFullPath();
+ if (fullPath != null) {
+ IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(fullPath));
+ if (res instanceof IFile) {
+ try {
+ return ((IFile) res).getCharset();
+ } catch (CoreException e) {
+ }
+ }
+ }
+ return InternalParserUtil.SYSTEM_DEFAULT_ENCODING;
+ }
+
@Override
public AbstractLanguage[] getLanguages(Object tuo, boolean bothForHeaders) {
if (tuo instanceof PotentialTranslationUnit) {