From b21be9a7d04e5ec61362f8474e9b2f6acf133bce Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 5 Jul 2007 15:38:20 +0000 Subject: [PATCH] Fix for 167100, using include guards outside of header. --- .../internal/index/tests/IndexBugsTests.java | 39 +++-- .../eclipse/cdt/core/index/IIndexInclude.java | 12 +- .../index/IndexBasedCodeReaderFactory.java | 34 ++++- .../core/parser/scanner2/BaseScanner.java | 133 +++++++----------- .../core/parser/scanner2/DOMScanner.java | 42 +++++- .../IIndexBasedCodeReaderFactory.java | 26 ++++ .../scanner2/IScannerPreprocessorLog.java | 17 +++ .../core/parser/scanner2/LocationMap.java | 17 ++- .../cdt/internal/core/pdom/PDOMWriter.java | 5 +- .../internal/core/pdom/dom/PDOMInclude.java | 29 ++-- .../eclipse/cdt/ui/tests/BaseUITestCase.java | 5 + 11 files changed, 232 insertions(+), 127 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IIndexBasedCodeReaderFactory.java 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 45086fa269a..591351334f2 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 @@ -740,24 +740,43 @@ public class IndexBugsTests extends BaseTestCase { // #include "header2.h" // int M; - public void _testIncludeGuardsOutsideOfHeader_Bug167100() throws Exception { + // #include "header2.h" + // #ifndef _h1 + // #include "header1.h" + // #endif + public void testIncludeGuardsOutsideOfHeader_Bug167100() throws Exception { final IIndexManager indexManager = CCorePlugin.getIndexManager(); - StringBuffer[] contents= getContentsForTest(4); + StringBuffer[] contents= getContentsForTest(5); IFile f1= TestSourceReader.createFile(fCProject.getProject(), "header1.h", contents[0].toString()); IFile f2= TestSourceReader.createFile(fCProject.getProject(), "header2.h", contents[1].toString()); IFile f3= TestSourceReader.createFile(fCProject.getProject(), "src.cpp", contents[2].toString()); indexManager.reindex(fCProject); waitForIndexer(); - IFile f4= TestSourceReader.createFile(fCProject.getProject(), "src2.cpp", contents[2].toString()); + IFile f4= TestSourceReader.createFile(fCProject.getProject(), "src2.cpp", contents[3].toString()); + IFile f5= TestSourceReader.createFile(fCProject.getProject(), "src3.cpp", contents[4].toString()); waitForIndexer(); IIndex index= indexManager.getIndex(fCProject); - IIndexBinding[] bindings= index.findBindings("v".toCharArray(), null, NPM); - assertEquals(1, bindings.length); - IIndexBinding binding= bindings[0]; - assertTrue(binding instanceof IVariable); - IIndexName[] names= index.findNames(binding, IIndex.FIND_ALL_OCCURENCES); - assertEquals(1, names.length); - assertEquals(f4.getFullPath().toString(), names[0].getFile().getLocation().getFullPath()); + index.acquireReadLock(); + try { + IIndexBinding[] bindings = index.findBindings("v".toCharArray(), IndexFilter.ALL, NPM); + assertEquals(1, bindings.length); + IIndexBinding binding = bindings[0]; + assertTrue(binding instanceof IVariable); + IIndexName[] names = index.findNames(binding, + IIndex.FIND_ALL_OCCURENCES); + assertEquals(1, names.length); + assertEquals(f4.getFullPath().toString(), names[0].getFile().getLocation().getFullPath()); + + IIndexFile idxFile= index.getFile(IndexLocationFactory.getWorkspaceIFL(f5)); + IIndexInclude[] includes= idxFile.getIncludes(); + assertEquals(2, includes.length); + assertTrue(includes[0].isActive()); + assertTrue(includes[0].isResolved()); + assertFalse(includes[1].isActive()); + assertTrue(includes[1].isResolved()); + } finally { + index.releaseReadLock(); + } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexInclude.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexInclude.java index 6406a422d37..fe134135140 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexInclude.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexInclude.java @@ -47,7 +47,7 @@ public interface IIndexInclude { /** * Returns the IIndexFileLocation of the file that is included by this - * directive. In case of an unresolved or inactive include null + * directive. In case of an unresolved include null * will be returned. * * @return the IIndexFileLocation of the file that is included by this @@ -59,7 +59,7 @@ public interface IIndexInclude { /** * Returns the simple name of the directive. This skips any leading - * direcories. E.g.: for '' 'types.h' will be returned. + * directories. E.g.: for '' 'types.h' will be returned. * @throws CoreException */ String getName() throws CoreException; @@ -87,7 +87,6 @@ public interface IIndexInclude { /** * Test whether this include is in active code (not skipped by conditional preprocessing). - * * @return whether this include is in active code * @throws CoreException */ @@ -95,6 +94,13 @@ public interface IIndexInclude { /** * Test whether this include has been resolved (found in the file system). + * Inactive includes are not resolved, unless they constitute a hidden dependency. + * This is the case when an include is inactive because it has been included before: + * + * #ifndef _header_h + * #include "header.h" + * #endif + * * * @return whether this is a resolved include * @throws CoreException diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java index 41d4c2c6ede..b9a7a77c40d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java @@ -39,15 +39,20 @@ import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.ICodeReaderCache; import org.eclipse.cdt.core.parser.IMacro; import org.eclipse.cdt.core.parser.ParserUtil; +import org.eclipse.cdt.internal.core.parser.scanner2.IIndexBasedCodeReaderFactory; import org.eclipse.cdt.internal.core.parser.scanner2.ObjectStyleMacro; import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro; import org.eclipse.core.runtime.CoreException; /** - * @author Doug Schaefer - * + * Code reader factory, that fakes code readers for header files already stored in the + * index. + * + *

+ * This interface is not intended to be implemented by clients. + *

*/ -public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { +public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory { public static interface CallbackHandler { boolean needToUpdate(IndexFileInfo fileInfo) throws CoreException; } @@ -78,7 +83,7 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { private Map/**/ iflCache; private List usedMacros = new ArrayList(); private Set/**/ fIncluded= new HashSet(); - /** The fallback code reader factory used in case a header file is not indexed */ + /** The fall-back code reader factory used in case a header file is not indexed */ private ICodeReaderFactory fFallBackFactory; private CallbackHandler fCallbackHandler; private final ICProject cproject; @@ -166,6 +171,7 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { } // record the macros we used. usedMacros.add(fi.fMacros); + setIncluded(fi); } return new CodeReader(canonicalPath, EMPTY_CHARS); } catch (NeedToParseException e) { @@ -184,6 +190,25 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { return ParserUtil.createReader(canonicalPath, null); } + public boolean hasFileBeenIncludedInCurrentTranslationUnit(String path) { + String canonicalPath= path; + if (!CASE_SENSITIVE_FILES) { + try { + File location= new File(path); + canonicalPath= location.getCanonicalPath(); + } + catch (IOException e) { + // just use the original + } + } + IIndexFileLocation loc= findLocation(canonicalPath); + IndexFileInfo info= (IndexFileInfo) fileInfoCache.get(loc); + if (info != null && isIncluded(info)) { + return true; + } + return false; + } + /** * Mark the given inclusion as included. * @param info @@ -234,7 +259,6 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory { getInfosForMacroDictionary(nextInfo, target); } } - setIncluded(fileInfo); } public void clearMacroAttachements() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java index abc31890a63..3784f5e841a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java @@ -129,6 +129,16 @@ abstract class BaseScanner implements IScanner { return arguments; } } + + protected interface IIncludeFileTester { + Object checkFile(String path, String fileName); + } + + final private IIncludeFileTester createCodeReaderTester= new IIncludeFileTester() { + public Object checkFile(String path, String fileName) { + return createReader(path, fileName); + } + }; protected ParserLanguage language; @@ -1800,8 +1810,7 @@ abstract class BaseScanner implements IScanner { */ protected abstract void processIf(int startPos, int endPos, boolean taken); - protected void handlePPInclude(int pos2, boolean include_next, - int startingLineNumber, boolean active) { + protected void handlePPInclude(int pos2, boolean include_next, int startingLineNumber, boolean active) { char[] buffer = bufferStack[bufferStackPos]; int limit = bufferLimit[bufferStackPos]; @@ -1929,78 +1938,55 @@ abstract class BaseScanner implements IScanner { endLine = getLineNumber(bufferPos[bufferStackPos]); skipToNewLine(); - if (active) { - findAndPushInclusion(filename, fileNameArray, local, include_next, false, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine); - } else { - processInclude(fileNameArray, local, active, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine); + if (parserMode == ParserMode.QUICK_PARSE && active) { + final Object inc= createInclusionConstruct( + fileNameArray, EMPTY_CHAR_ARRAY, local, startOffset, startingLineNumber, + nameOffset, nameEndOffset, nameLine, endOffset, endLine, false); + quickParsePushPopInclusion(inc); + } + else { + CodeReader reader= null; + if (active) { + reader= findInclusion(filename, local, include_next); + if (reader != null) { + final Object inc = createInclusionConstruct( + fileNameArray, reader.filename, local, startOffset, startingLineNumber, + nameOffset, nameEndOffset, nameLine, endOffset, endLine, false); + pushContext(reader.buffer, new InclusionData(reader, inc, false)); + } + } + if (reader == null) { + processInclude(fileNameArray, local, include_next, active, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine); + if (active) { + handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, startOffset, fileNameArray); + } + } } } /** * Process an include directive without following the inclusion. - * - * @param fileName - * @param local - * @param active - * @param startOffset - * @param nameOffset - * @param nameEndOffset - * @param endOffset - * @param startingLineNumber - * @param nameLine - * @param endLine */ - protected void processInclude(char[] fileName, boolean local, boolean active, int startOffset, int nameOffset, + protected void processInclude(char[] fileName, boolean local, boolean include_next, boolean active, int startOffset, int nameOffset, int nameEndOffset, int endOffset, int startingLineNumber, int nameLine, int endLine) { // default: do nothing } - /** - * @param filename - * @param fileNameArray - * @param local - * @param include_next - * @param includeOnce - * @param startOffset - * @param nameOffset - * @param nameEndOffset - * @param endOffset - * @param startingLine - * @param nameLine - * @param endLine - */ - protected void findAndPushInclusion(String filename, char[] fileNameArray, boolean local, boolean include_next, boolean includeOnce, int startOffset, int nameOffset, int nameEndOffset, int endOffset, int startingLine, int nameLine, int endLine) { - if (parserMode == ParserMode.QUICK_PARSE) { - Object inclusion = createInclusionConstruct(fileNameArray, - EMPTY_CHAR_ARRAY, local, startOffset, startingLine, - nameOffset, nameEndOffset, nameLine, endOffset, endLine, - false); - quickParsePushPopInclusion(inclusion); - return; - } - - CodeReader reader = null; + private CodeReader findInclusion(final String filename, final boolean local, final boolean include_next) { + return (CodeReader) findInclusion(filename, local, include_next, createCodeReaderTester); + } + + protected Object findInclusion(final String filename, final boolean local, final boolean include_next, + final IIncludeFileTester tester) { + Object reader = null; // filename is an absolute path or it is a Linux absolute path on a windows machine if (new File(filename).isAbsolute() || filename.startsWith("/")) { //$NON-NLS-1$ - reader = createReader( EMPTY_STRING, filename ); - if (reader != null) { - pushContext(reader.buffer, new InclusionData(reader, - createInclusionConstruct(fileNameArray, - reader.filename, local, startOffset, - startingLine, nameOffset, - nameEndOffset, nameLine, endOffset, - endLine, false), includeOnce)); - return; - } - processInclude(fileNameArray, local, true, startOffset, nameOffset, nameEndOffset, endOffset, startingLine, nameLine, endLine); - handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, startOffset, - fileNameArray); - return; + return tester.checkFile( EMPTY_STRING, filename ); } File currentDirectory = null; if (local || include_next) { - // if the include is eclosed in quotes OR we are in an include_next + // if the include is enclosed in quotes OR we are in an include_next // then we need to know what the current directory is! File file = new File(String.valueOf(getCurrentFilename())); currentDirectory = file.getParentFile(); @@ -2010,24 +1996,15 @@ abstract class BaseScanner implements IScanner { // Check to see if we find a match in the current directory if (currentDirectory != null) { String absolutePath = currentDirectory.getAbsolutePath(); - reader = createReader(absolutePath, filename); + reader = tester.checkFile(absolutePath, filename); if (reader != null) { - pushContext(reader.buffer, new InclusionData(reader, - createInclusionConstruct(fileNameArray, - reader.filename, local, startOffset, - startingLine, nameOffset, - nameEndOffset, nameLine, endOffset, - endLine, false), includeOnce)); - return; + return reader; } } } - // if we're not include_next, then we are looking for the - // first occurance of the file, otherwise, we ignore all the paths - // before - // the - // current directory + // if we're not include_next, then we are looking for the first occurrence of + // the file, otherwise, we ignore all the paths before the current directory String [] includePathsToUse = stdIncludePaths; if( local && locIncludePaths != null && locIncludePaths.length > 0 ) { includePathsToUse = new String[locIncludePaths.length + stdIncludePaths.length]; @@ -2040,21 +2017,13 @@ abstract class BaseScanner implements IScanner { if (include_next) startpos = findIncludePos(includePathsToUse, currentDirectory) + 1; for (int i = startpos; i < includePathsToUse.length; ++i) { - reader = createReader(includePathsToUse[i], filename); + reader = tester.checkFile(includePathsToUse[i], filename); if (reader != null) { - pushContext(reader.buffer, new InclusionData(reader, - createInclusionConstruct(fileNameArray, - reader.filename, local, startOffset, - startingLine, nameOffset, - nameEndOffset, nameLine, endOffset, - endLine, false), includeOnce)); - return; + return reader; } } } - processInclude(fileNameArray, local, true, startOffset, nameOffset, nameEndOffset, endOffset, startingLine, nameLine, endLine); - handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, startOffset, - fileNameArray); + return null; } protected abstract CodeReader createReader(String path, String fileName); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java index cdf93ecd667..b438b307355 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java @@ -13,6 +13,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.parser.scanner2; +import java.io.File; import java.util.Iterator; import java.util.List; @@ -39,6 +40,17 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils; public class DOMScanner extends BaseScanner { private static final Class CHAR_ARRAY_CLASS = new char[]{}.getClass(); + private final IScannerPreprocessorLog locationMap = new LocationMap(); + private final IIncludeFileTester createPathTester= new IIncludeFileTester() { + public Object checkFile(String path, String fileName) { + path= ScannerUtility.createReconciledPath(path, fileName); + if (new File(path).exists()) { + return path; + } + return null; + } + }; + protected final ICodeReaderFactory codeReaderFactory; protected int[] bufferDelta = new int[bufferInitialSize]; @@ -123,8 +135,6 @@ public class DOMScanner extends BaseScanner { return null; } - final IScannerPreprocessorLog locationMap = new LocationMap(); - /* * (non-Javadoc) * @@ -176,9 +186,30 @@ public class DOMScanner extends BaseScanner { /* * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processInclude(char[], boolean, boolean, int, int, int, int, int, int, int) */ - protected void processInclude(char[] filename, boolean local, boolean active, int startOffset, int nameOffset, - int nameEndOffset, int endOffset, int startingLineNumber, int nameLine, int endLine) { - locationMap.encounterPoundInclude(getGlobalOffset(startOffset), getGlobalOffset(nameOffset), getGlobalOffset(nameEndOffset), getGlobalOffset(endOffset), filename, !local, active); + protected void processInclude(char[] filename, boolean local, boolean include_next, boolean active, + int startOffset, int nameOffset, int nameEndOffset, int endOffset, int startingLineNumber, + int nameLine, int endLine) { + char[] pchars= null; + String path= (String) findInclusion(new String(filename), local, include_next, createPathTester); + if (path != null) { + if (codeReaderFactory instanceof IIndexBasedCodeReaderFactory) { + // fast indexer + if (((IIndexBasedCodeReaderFactory) codeReaderFactory).hasFileBeenIncludedInCurrentTranslationUnit(path)) { + pchars= path.toCharArray(); + } + } + else { + // full indexer + pchars= path.toCharArray(); + if (!includedFiles.containsKey(pchars)) { + // not a hidden dependency, don't report it. + pchars= null; + } + } + } + locationMap.encounterPoundInclude(getGlobalOffset(startOffset), getGlobalOffset(nameOffset), + getGlobalOffset(nameEndOffset), getGlobalOffset(endOffset), + filename, pchars, !local, active); } /* @@ -221,6 +252,7 @@ public class DOMScanner extends BaseScanner { locationMap.startInclusion(((InclusionData) data).reader, inc.o, getGlobalOffset(getCurrentOffset())+1, inc.nameOffset, inc.nameEndoffset, inc.name, inc.systemInclude); bufferDelta[bufferStackPos + 1] = 0; + includedFiles.put(inc.pt); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IIndexBasedCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IIndexBasedCodeReaderFactory.java new file mode 100644 index 00000000000..cb122357ccc --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IIndexBasedCodeReaderFactory.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.parser.scanner2; + +import org.eclipse.cdt.core.dom.ICodeReaderFactory; + +/** + * The index based code-reader factory fakes the inclusion of files that are already indexed. + * When trying to figure out whether a specific header has been included or not, the factory + * has to be consulted. + * @since 4.0.1 + */ +public interface IIndexBasedCodeReaderFactory extends ICodeReaderFactory { + /** + * Returns whether or not the file has been included. + */ + boolean hasFileBeenIncludedInCurrentTranslationUnit(String path); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java index efcb4c01baa..4941d93aafa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java @@ -78,8 +78,25 @@ public interface IScannerPreprocessorLog { public void encounterPoundUndef(int startOffset, int endOffset, char[] symbol, int nameOffset, IMacroDefinition macroDefinition); + /** + * @deprecated use {@link #encounterPoundInclude(int, int, int, int, char[], char[], boolean, boolean)}. + */ public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset, char[] name, boolean systemInclude, boolean active); + /** + * Report an include that is not actually processed ({@link #startInclusion(CodeReader, int, int, int, int, char[], boolean)} + * To report hidden dependencies (bug 167100) you can use the path parameter. + * @param startOffset + * @param nameOffset + * @param nameEndOffset + * @param endOffset + * @param name the name of the include as found in the source + * @param hiddenDependency a file-path in case the include is a hidden dependency, or null. + * @param systemInclude + * @param active + */ + public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset, char[] name, char[] hiddenDependency, boolean systemInclude, boolean active); + public void encounterProblem(IASTProblem problem); public IMacroDefinition registerBuiltinObjectStyleMacro(ObjectStyleMacro macro); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java index 205c478a7c5..c1721dcf81f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java @@ -581,16 +581,18 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { public final int fNameOffset; public final int fNameEndOffset; public final char[] fName; + public final char[] fPath; public final boolean fSystemInclude; public final boolean fIsActive; public final boolean fIsResolved; public _Include(_CompositeContext parent, int startOffset, int endOffset, int nameOffset, int nameEndoffset, - char[] name, boolean systemInclude, boolean active, boolean resolved) { + char[] name, char[] path, boolean systemInclude, boolean active, boolean resolved) { super(parent, startOffset, endOffset); fNameOffset= nameOffset; fNameEndOffset= nameEndoffset; fName= name; + fPath= path == null ? name : path; fSystemInclude= systemInclude; fIsActive= active; fIsResolved= resolved; @@ -1754,7 +1756,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { } private IASTPreprocessorIncludeStatement createASTInclusion(_Include inc) { - ASTInclusionStatement result = new ASTInclusionStatement(inc.fName); + ASTInclusionStatement result = new ASTInclusionStatement(inc.fPath); result.setOffsetAndLength(inc.context_directive_start, inc.getDirectiveLength()); result.startOffset = inc.getContextStart(); result.endOffset = inc.context_directive_end; @@ -2413,9 +2415,14 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /* * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#encounterPoundInclude(int, int, int, int, char[], boolean, boolean) */ - public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset, char[] name, - boolean systemInclude, boolean active) { - currentContext.addSubContext(new _Include(currentContext, startOffset, endOffset, nameOffset, nameEndOffset, name, systemInclude, active, false)); + public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset, + char[] name, boolean systemInclude, boolean active) { + encounterPoundInclude(startOffset, nameOffset, nameEndOffset, endOffset, name, null, systemInclude, active); + } + + public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset, + char[] name, char[] path, boolean systemInclude, boolean active) { + currentContext.addSubContext(new _Include(currentContext, startOffset, endOffset, nameOffset, nameEndOffset, name, path, systemInclude, active, path != null)); } /* 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 655e01b0584..3a4ffd178ca 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 @@ -462,8 +462,9 @@ abstract public class PDOMWriter { info.fStatement= include; if (include.isResolved()) { info.fLocation= findLocation(include.getPath()); - info.fIsContext= contextIncludes.contains(include) || - clearedContexts.contains(info.fLocation); + info.fIsContext= include.isActive() && + (contextIncludes.contains(include) || + clearedContexts.contains(info.fLocation)); } } index.setFileContent(file, includeInfos, macros, names); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java index 8f392b2251b..e4cf5d5169e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMInclude.java @@ -31,24 +31,23 @@ import org.eclipse.core.runtime.CoreException; */ public class PDOMInclude implements IIndexFragmentInclude { + private static final int INCLUDES_FILE_OR_NAME = 0; + private static final int INCLUDED_BY = 4; + private static final int INCLUDES_NEXT = 8; + private static final int INCLUDED_BY_NEXT = 12; + private static final int INCLUDED_BY_PREV = 16; + private static final int NODE_OFFSET_OFFSET = 20; + private static final int NODE_LENGTH_OFFSET = 24; + private static final int FLAG_OFFSET = 26; + private static final int RECORD_SIZE = 27; + + private static final int FLAG_SYSTEM_INCLUDE = 1; + private static final int FLAG_INACTIVE_INCLUDE = 2; + private static final int FLAG_UNRESOLVED_INCLUDE = 4; + private final PDOM pdom; private final int record; - private final int INCLUDES_FILE_OR_NAME = 0; - private final int INCLUDED_BY = 4; - private final int INCLUDES_NEXT = 8; - private final int INCLUDED_BY_NEXT = 12; - private final int INCLUDED_BY_PREV = 16; - private static final int NODE_OFFSET_OFFSET = 20; - private static final int NODE_LENGTH_OFFSET = 24; - private static final int FLAG_OFFSET = 26; - - private static final int FLAG_SYSTEM_INCLUDE = 1; - private static final int FLAG_INACTIVE_INCLUDE = 2; - private static final int FLAG_UNRESOLVED_INCLUDE = 4; - - private final int RECORD_SIZE = 27; - // cached fields private String fName= null; diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java index 460ee90f877..b07a022f9b7 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java @@ -42,6 +42,7 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.handlers.IHandlerService; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFile; @@ -104,6 +105,10 @@ public class BaseUITestCase extends BaseTestCase { } finally { index.releaseReadLock(); + int time= (int) (endTime- System.currentTimeMillis()); + if (time > 0) { + CCorePlugin.getIndexManager().joinIndexer(time, NPM); + } } } throw new Exception("Indexer did not complete in time!");