mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 18:56:02 +02:00
Bug 412463 - Code completion stops working in the presence of predefined
macro Change-Id: Iabeb0742ce5564a150f859185c0f8eb64805955a Signed-off-by: Nathan Ridge <zeratul976@hotmail.com> Reviewed-on: https://git.eclipse.org/r/14399 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
parent
6df967d0d4
commit
8f78f34f19
4 changed files with 87 additions and 33 deletions
|
@ -915,7 +915,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
||||||
for (IIndexFile indexFile : index.getFiles(linkageID, ifl)) {
|
for (IIndexFile indexFile : index.getFiles(linkageID, ifl)) {
|
||||||
int score= indexFile.getMacros().length * 2;
|
int score= indexFile.getMacros().length * 2;
|
||||||
IIndexFile context= getParsedInContext(indexFile);
|
IIndexFile context= getParsedInContext(indexFile);
|
||||||
if (isSourceFile(context))
|
if (isSourceFile(context, getCProject().getProject()))
|
||||||
score++;
|
score++;
|
||||||
if (score > bestScore) {
|
if (score > bestScore) {
|
||||||
bestScore= score;
|
bestScore= score;
|
||||||
|
@ -936,7 +936,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IIndexFile getParsedInContext(IIndexFile indexFile) throws CoreException {
|
public static IIndexFile getParsedInContext(IIndexFile indexFile) throws CoreException {
|
||||||
HashSet<IIndexFile> visited= new HashSet<IIndexFile>();
|
HashSet<IIndexFile> visited= new HashSet<IIndexFile>();
|
||||||
// Bug 199412, may recurse.
|
// Bug 199412, may recurse.
|
||||||
while (visited.add(indexFile)) {
|
while (visited.add(indexFile)) {
|
||||||
|
@ -949,12 +949,12 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <code>true</code> if the given file was parsed in a context of a source file.
|
* Returns <code>true</code> if the given file is a source file.
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
private boolean isSourceFile(IIndexFile indexFile) throws CoreException {
|
public static boolean isSourceFile(IIndexFile indexFile, IProject project) throws CoreException {
|
||||||
String path = indexFile.getLocation().getURI().getPath();
|
String path = indexFile.getLocation().getURI().getPath();
|
||||||
IContentType cType = CCorePlugin.getContentType(getCProject().getProject(), path);
|
IContentType cType = CCorePlugin.getContentType(project, path);
|
||||||
if (cType == null)
|
if (cType == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ public interface IIndexFragment {
|
||||||
* <p>
|
* <p>
|
||||||
* When a header file is stored in the index in multiple variants for different sets of macro
|
* When a header file is stored in the index in multiple variants for different sets of macro
|
||||||
* definitions, this method will return an arbitrary one of these variants.
|
* definitions, this method will return an arbitrary one of these variants.
|
||||||
*
|
*
|
||||||
* @param linkageID the id of the linkage in which the file has been parsed.
|
* @param linkageID the id of the linkage in which the file has been parsed.
|
||||||
* @param location the IIndexFileLocation representing the location of the file
|
* @param location the IIndexFileLocation representing the location of the file
|
||||||
* @return the file for the location, or <code>null</code> if the file is not present in
|
* @return the file for the location, or <code>null</code> if the file is not present in
|
||||||
|
@ -114,7 +114,7 @@ public interface IIndexFragment {
|
||||||
* May return <code>null</code>, if no such file exists.
|
* May return <code>null</code>, if no such file exists.
|
||||||
* This method may only return files that are actually managed by this fragment.
|
* This method may only return files that are actually managed by this fragment.
|
||||||
* This method returns files without content, also.
|
* This method returns files without content, also.
|
||||||
*
|
*
|
||||||
* @param linkageID the id of the linkage in which the file has been parsed.
|
* @param linkageID the id of the linkage in which the file has been parsed.
|
||||||
* @param location the IIndexFileLocation representing the location of the file
|
* @param location the IIndexFileLocation representing the location of the file
|
||||||
* @param macroDictionary The names and definitions of the macros used to disambiguate between
|
* @param macroDictionary The names and definitions of the macros used to disambiguate between
|
||||||
|
@ -132,10 +132,7 @@ public interface IIndexFragment {
|
||||||
* for different sets of macro definitions.
|
* for different sets of macro definitions.
|
||||||
* This method may only return files that are actually managed by this fragment.
|
* This method may only return files that are actually managed by this fragment.
|
||||||
* This method returns files without content, also.
|
* This method returns files without content, also.
|
||||||
* <p>
|
*
|
||||||
* When a header file is stored in the index in multiple variants for different sets of macro
|
|
||||||
* definitions, this method will return an arbitrary one of these variants.
|
|
||||||
*
|
|
||||||
* @param linkageID the id of the linkage in which the file has been parsed.
|
* @param linkageID the id of the linkage in which the file has been parsed.
|
||||||
* @param location the IIndexFileLocation representing the location of the file
|
* @param location the IIndexFileLocation representing the location of the file
|
||||||
* @return the files for the location and the linkage.
|
* @return the files for the location and the linkage.
|
||||||
|
@ -224,7 +221,7 @@ public interface IIndexFragment {
|
||||||
* Searches for all names that resolve to the given binding. You can limit the result to
|
* Searches for all names that resolve to the given binding. You can limit the result to
|
||||||
* references, declarations or definitions, or a combination of those.
|
* references, declarations or definitions, or a combination of those.
|
||||||
* @param binding a binding for which names are searched for
|
* @param binding a binding for which names are searched for
|
||||||
* @param flags a combination of {@link #FIND_DECLARATIONS}, {@link #FIND_DEFINITIONS},
|
* @param flags a combination of {@link #FIND_DECLARATIONS}, {@link #FIND_DEFINITIONS},
|
||||||
* {@link #FIND_REFERENCES} and {@link #FIND_NON_LOCAL_ONLY}
|
* {@link #FIND_REFERENCES} and {@link #FIND_NON_LOCAL_ONLY}
|
||||||
* @return an array of names
|
* @return an array of names
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom;
|
package org.eclipse.cdt.internal.core.pdom;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -23,14 +23,17 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexFile;
|
||||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||||
import org.eclipse.cdt.core.index.IIndexLocationConverter;
|
import org.eclipse.cdt.core.index.IIndexLocationConverter;
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||||
import org.eclipse.cdt.internal.core.index.FileContentKey;
|
import org.eclipse.cdt.internal.core.index.FileContentKey;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
||||||
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
||||||
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
|
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
|
||||||
|
import org.eclipse.cdt.internal.core.model.TranslationUnit;
|
||||||
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
|
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
|
||||||
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
|
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
|
||||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
|
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
|
||||||
|
@ -43,7 +46,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacroReferenceName;
|
||||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
private boolean fClearedBecauseOfVersionMismatch= false;
|
private boolean fClearedBecauseOfVersionMismatch= false;
|
||||||
private boolean fCreatedFromScratch= false;
|
private boolean fCreatedFromScratch= false;
|
||||||
private ASTFilePathResolver fPathResolver;
|
private ASTFilePathResolver fPathResolver;
|
||||||
|
@ -55,12 +58,12 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
|
Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
|
||||||
this(dbPath, locationConverter, ChunkCache.getSharedInstance(), linkageFactoryMappings);
|
this(dbPath, locationConverter, ChunkCache.getSharedInstance(), linkageFactoryMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WritablePDOM(File dbPath, IIndexLocationConverter locationConverter, ChunkCache cache,
|
public WritablePDOM(File dbPath, IIndexLocationConverter locationConverter, ChunkCache cache,
|
||||||
Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
|
Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
|
||||||
super(dbPath, locationConverter, cache, linkageFactoryMappings);
|
super(dbPath, locationConverter, cache, linkageFactoryMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setASTFilePathResolver(ASTFilePathResolver resolver) {
|
public void setASTFilePathResolver(ASTFilePathResolver resolver) {
|
||||||
fPathResolver= resolver;
|
fPathResolver= resolver;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +72,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location, ISignificantMacros sigMacros) throws CoreException {
|
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location, ISignificantMacros sigMacros) throws CoreException {
|
||||||
if (uncommittedKey != null && uncommittedKey.equals(new FileContentKey(linkageID, location, sigMacros)))
|
if (uncommittedKey != null && uncommittedKey.equals(new FileContentKey(linkageID, location, sigMacros)))
|
||||||
return uncommittedFile;
|
return uncommittedFile;
|
||||||
|
|
||||||
return super.addFile(linkageID, location, sigMacros);
|
return super.addFile(linkageID, location, sigMacros);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,11 +141,11 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFileContent(IIndexFragmentFile sourceFile, IncludeInformation[] includes,
|
public void addFileContent(IIndexFragmentFile sourceFile, IncludeInformation[] includes,
|
||||||
IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver pathResolver,
|
IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver pathResolver,
|
||||||
YieldableIndexLock lock) throws CoreException, InterruptedException {
|
YieldableIndexLock lock) throws CoreException, InterruptedException {
|
||||||
assert sourceFile.getIndexFragment() == this;
|
assert sourceFile.getIndexFragment() == this;
|
||||||
|
|
||||||
PDOMFile pdomFile = (PDOMFile) sourceFile;
|
PDOMFile pdomFile = (PDOMFile) sourceFile;
|
||||||
pdomFile.addMacros(macros);
|
pdomFile.addMacros(macros);
|
||||||
final ASTFilePathResolver origResolver= fPathResolver;
|
final ASTFilePathResolver origResolver= fPathResolver;
|
||||||
|
@ -154,7 +157,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
}
|
}
|
||||||
// Includes expose the temporary file in the index, we must not yield the lock beyond this point.
|
// Includes expose the temporary file in the index, we must not yield the lock beyond this point.
|
||||||
pdomFile.addIncludesTo(includes);
|
pdomFile.addIncludesTo(includes);
|
||||||
|
|
||||||
final IIndexFileLocation location = pdomFile.getLocation();
|
final IIndexFileLocation location = pdomFile.getLocation();
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
fEvent.fClearedFiles.remove(location);
|
fEvent.fClearedFiles.remove(location);
|
||||||
|
@ -167,37 +170,37 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
assert file.getIndexFragment() == this;
|
assert file.getIndexFragment() == this;
|
||||||
IIndexFileLocation location = file.getLocation();
|
IIndexFileLocation location = file.getLocation();
|
||||||
PDOMFile pdomFile = (PDOMFile) file;
|
PDOMFile pdomFile = (PDOMFile) file;
|
||||||
pdomFile.clear();
|
pdomFile.clear();
|
||||||
|
|
||||||
fEvent.fClearedFiles.add(location);
|
fEvent.fClearedFiles.add(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() throws CoreException {
|
public void clear() throws CoreException {
|
||||||
super.clear();
|
super.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() throws CoreException {
|
public void flush() throws CoreException {
|
||||||
super.flush();
|
super.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setProperty(String propertyName, String value) throws CoreException {
|
public void setProperty(String propertyName, String value) throws CoreException {
|
||||||
if (IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName)
|
if (IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName)
|
||||||
|| IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(propertyName)) {
|
|| IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(propertyName)) {
|
||||||
throw new IllegalArgumentException("Property " + value + " may not be written to"); //$NON-NLS-1$ //$NON-NLS-2$
|
throw new IllegalArgumentException("Property " + value + " may not be written to"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
}
|
}
|
||||||
new DBProperties(db, PROPERTIES).setProperty(propertyName, value);
|
new DBProperties(db, PROPERTIES).setProperty(propertyName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses the specified location converter to update each internal representation of a file
|
* Uses the specified location converter to update each internal representation of a file
|
||||||
* location. The file index is rebuilt with the new representations. Individual PDOMFile records
|
* location. The file index is rebuilt with the new representations. Individual PDOMFile records
|
||||||
* are unmoved so as to maintain referential integrity with other PDOM records.
|
* are unmoved so as to maintain referential integrity with other PDOM records.
|
||||||
*
|
*
|
||||||
* <b>A write-lock must be obtained before calling this method</b>
|
* <b>A write-lock must be obtained before calling this method</b>
|
||||||
*
|
*
|
||||||
* @param newConverter the converter to use to update internal file representations
|
* @param newConverter the converter to use to update internal file representations
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
|
@ -250,12 +253,47 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
void setCreatedFromScratch(boolean createdFromScratch) {
|
void setCreatedFromScratch(boolean createdFromScratch) {
|
||||||
fCreatedFromScratch = createdFromScratch;
|
fCreatedFromScratch = createdFromScratch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final boolean isPermanentlyReadOnly() {
|
protected final boolean isPermanentlyReadOnly() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the best file for the given location, linkage, and translation unit.
|
||||||
|
* May return <code>null</code>, if no such file exists.
|
||||||
|
*
|
||||||
|
* The "best" file (variant) is the one with the most content, as measured
|
||||||
|
* by the total number of macros defined in the file. The rationale is that
|
||||||
|
* often one of the variants will contain most of the code and the others
|
||||||
|
* just small pieces, and we are usually interested in the one with most of
|
||||||
|
* the code. As a tiebreaker, a variant that was parsed in the context of a
|
||||||
|
* source file is preferred, since a header parsed outside of the context of
|
||||||
|
* a code file may not represent code that a compiler actually sees.
|
||||||
|
*
|
||||||
|
* @param linkageID the id of the linkage in which the file has been parsed.
|
||||||
|
* @param location the IIndexFileLocation representing the location of the file
|
||||||
|
* @param tu the translation unit from which 'location' originates
|
||||||
|
* @return the best file for the location, or <code>null</code> if the file is not
|
||||||
|
* present in the index
|
||||||
|
* @throws CoreException
|
||||||
|
*/
|
||||||
|
private PDOMFile getBestFile(int linkageID, IIndexFileLocation location, ITranslationUnit tu) throws CoreException {
|
||||||
|
IIndexFile[] files = getFiles(linkageID, location);
|
||||||
|
IIndexFile best = null;
|
||||||
|
int bestScore = -1;
|
||||||
|
for (IIndexFile file : files) {
|
||||||
|
int score = file.getMacros().length * 2;
|
||||||
|
if (TranslationUnit.isSourceFile(TranslationUnit.getParsedInContext(file), tu.getCProject().getProject()))
|
||||||
|
score++;
|
||||||
|
if (score > bestScore) {
|
||||||
|
bestScore = score;
|
||||||
|
best = file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (PDOMFile) best;
|
||||||
|
}
|
||||||
|
|
||||||
public PDOMFile getFileForASTNode(int linkageID, IASTNode node) throws CoreException {
|
public PDOMFile getFileForASTNode(int linkageID, IASTNode node) throws CoreException {
|
||||||
if (fPathResolver != null && node != null) {
|
if (fPathResolver != null && node != null) {
|
||||||
IASTFileLocation loc= node.getFileLocation();
|
IASTFileLocation loc= node.getFileLocation();
|
||||||
|
@ -265,7 +303,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
IIndexFileLocation location = fPathResolver.resolveASTPath(loc.getFileName());
|
IIndexFileLocation location = fPathResolver.resolveASTPath(loc.getFileName());
|
||||||
if (uncommittedKey != null && uncommittedKey.equals(new FileContentKey(linkageID, location, sigMacros)))
|
if (uncommittedKey != null && uncommittedKey.equals(new FileContentKey(linkageID, location, sigMacros)))
|
||||||
return fileBeingUpdated != null ? fileBeingUpdated : uncommittedFile;
|
return fileBeingUpdated != null ? fileBeingUpdated : uncommittedFile;
|
||||||
return getFile(linkageID, location, sigMacros);
|
return getBestFile(linkageID, location, node.getTranslationUnit().getOriginatingTranslationUnit());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,13 +312,13 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
||||||
|
|
||||||
private ISignificantMacros getSignificantMacros(IASTNode node, IASTFileLocation loc) throws CoreException {
|
private ISignificantMacros getSignificantMacros(IASTNode node, IASTFileLocation loc) throws CoreException {
|
||||||
IASTPreprocessorIncludeStatement owner= loc.getContextInclusionStatement();
|
IASTPreprocessorIncludeStatement owner= loc.getContextInclusionStatement();
|
||||||
if (owner != null)
|
if (owner != null)
|
||||||
return owner.getSignificantMacros();
|
return owner.getSignificantMacros();
|
||||||
|
|
||||||
IASTTranslationUnit tu = node.getTranslationUnit();
|
IASTTranslationUnit tu = node.getTranslationUnit();
|
||||||
if (tu != null)
|
if (tu != null)
|
||||||
return tu.getSignificantMacros();
|
return tu.getSignificantMacros();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1308,8 +1308,27 @@ public class CompletionTests extends AbstractContentAssistTest {
|
||||||
// void foo() {
|
// void foo() {
|
||||||
// __LINE__;
|
// __LINE__;
|
||||||
// }
|
// }
|
||||||
public void testLineMacro_Bug412463() throws Exception {
|
public void testPreprocessorProvidedMacro_Bug412463() throws Exception {
|
||||||
final String[] expected = { "Cat", "meow(void)" };
|
final String[] expected = { "Cat", "meow(void)" };
|
||||||
assertContentAssistResults(fCursorOffset, expected, true, COMPARE_ID_STRINGS);
|
assertContentAssistResults(fCursorOffset, expected, true, COMPARE_ID_STRINGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct Cat {
|
||||||
|
// void meow();
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// struct Waldo {
|
||||||
|
// void bar() {
|
||||||
|
// c./*cursor*/
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Cat c;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// int x = __CDT_PARSER__;
|
||||||
|
public void testPredefinedMacro_Bug412463() throws Exception {
|
||||||
|
final String[] expected = { "Cat", "meow(void)" };
|
||||||
|
assertContentAssistResults(fCursorOffset, expected, true, COMPARE_ID_STRINGS);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue