diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java index 524dda86818..2dcd6ebfa22 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java @@ -58,6 +58,7 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV private IASTName fDefinition; private IASTName fDeclarations[]; private IType fType; + private IValue fInitialValue = IntegralValue.NOT_INITIALIZED; private boolean fAllResolved; /** @@ -109,10 +110,12 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV fDeclarations = ArrayUtil.append(IASTName.class, fDeclarations, name); } } - // Array types may be incomplete. + // An array type may be incomplete and needs to be recalculated. if (fType instanceof IArrayType) { fType = null; } + // Initial value has to be recalculated. + fInitialValue = IntegralValue.NOT_INITIALIZED; } @Override @@ -238,6 +241,13 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV @Override public IValue getInitialValue() { + if (fInitialValue == IntegralValue.NOT_INITIALIZED) { + fInitialValue = computeInitialValue(); + } + return fInitialValue; + } + + private IValue computeInitialValue() { Set recursionProtectionSet = fInitialValueInProgress.get(); if (!recursionProtectionSet.add(this)) { return IntegralValue.UNKNOWN; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableTemplate.java index 6f06dbc7b60..3fc879be5aa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableTemplate.java @@ -19,11 +19,13 @@ import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.internal.core.dom.parser.IntegralValue; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; public class CPPVariableTemplate extends CPPTemplateDefinition implements ICPPVariableTemplate, ICPPInternalDeclaredVariable { private IType fType; + private IValue fInitialValue = IntegralValue.NOT_INITIALIZED; private boolean fAllResolved; private ICPPPartialSpecialization[] partialSpecializations = ICPPPartialSpecialization.EMPTY_ARRAY; @@ -61,6 +63,13 @@ public class CPPVariableTemplate extends CPPTemplateDefinition @Override public IValue getInitialValue() { + if (fInitialValue == IntegralValue.NOT_INITIALIZED) { + fInitialValue = computeInitialValue(); + } + return fInitialValue; + } + + private IValue computeInitialValue() { return VariableHelpers.getInitialValue((IASTName) getDefinition(), (IASTName[]) getDeclarations(), getType()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalDeclaredVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalDeclaredVariable.java index e1946184d29..7f3e4c4219d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalDeclaredVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalDeclaredVariable.java @@ -10,6 +10,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +/** + * A common interface for CPPVariable and CPPVariableTemplate. + */ public interface ICPPInternalDeclaredVariable extends ICPPInternalVariable { /** * Informs the variable that all its declarations and definitions have already been added. 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 44b2f42bbf7..7ca4de3ea3e 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 @@ -44,6 +44,7 @@ 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; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias; @@ -59,6 +60,7 @@ import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.ISignificantMacros; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalDeclaredVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.index.FileContentKey; import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; @@ -356,6 +358,7 @@ public abstract class PDOMWriter implements IPDOMASTProcessor { private void resolveNames(Data data, IProgressMonitor monitor) { long start= System.currentTimeMillis(); + List variables = new ArrayList<>(); SubMonitor progress = SubMonitor.convert(monitor, data.fSelectedFiles.length); for (FileInAST file : data.fSelectedFiles) { Symbols symbols= data.fSymbolMap.get(file.includeStatement); @@ -367,10 +370,13 @@ public abstract class PDOMWriter implements IPDOMASTProcessor { final IASTName[] na= j.next(); final IASTName name = na[0]; progress2.split(1); - if (name != null) { // should not be null, just be defensive. - Throwable th= null; + if (name != null) { // Should not be null, just be defensive. try { final IBinding binding = name.resolveBinding(); + if (binding instanceof ICPPInternalDeclaredVariable) { + variables.add((ICPPInternalDeclaredVariable) binding); + } + if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME && (((IASTName) name.getParent()).getBinding() == binding || binding instanceof ICPPFunctionTemplate)) { @@ -401,15 +407,10 @@ public abstract class PDOMWriter implements IPDOMASTProcessor { } else { fStatistics.fDeclarationCount++; } - } catch (RuntimeException e) { - th= e; - } catch (StackOverflowError e) { - th= e; - } - if (th != null) { + } catch (RuntimeException | StackOverflowError e) { if (!reported) { data.fStatuses.add(CCorePlugin.createStatus(NLS.bind(Messages.PDOMWriter_errorResolvingName, - name.toString(), file.fileContentKey.getLocation().getURI().getPath()), th)); + name.toString(), file.fileContentKey.getLocation().getURI().getPath()), e)); } reported= true; j.remove(); @@ -417,6 +418,21 @@ public abstract class PDOMWriter implements IPDOMASTProcessor { } } } + + // Precalculate types and initial values of all fields to avoid doing it later when writing + // to the index. + for (ICPPInternalDeclaredVariable variable : variables) { + variable.allDeclarationsDefinitionsAdded(); + // TODO(sprigogin): It would be beneficial to precalculate types and initial values of all + // indexed variables not just fields. It should be done carefully to avoid + // unnecesssary overhead of doing it for variables that are not being indexed. + if (variable instanceof ICPPField) { + // Type and initial value will be cached by the variable. + variable.getType(); + variable.getInitialValue(); + } + } + fStatistics.fResolutionTime += System.currentTimeMillis() - start; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index f4a6e743db5..1d35959666f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -704,7 +704,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { } } else if (binding instanceof ICPPField) { if (parent instanceof PDOMCPPClassType || parent instanceof PDOMCPPClassSpecialization) { - if(binding instanceof ICPPFieldTemplate) { + if (binding instanceof ICPPFieldTemplate) { pdomBinding = new PDOMCPPFieldTemplate(this, parent, (ICPPFieldTemplate) binding); } else { pdomBinding = new PDOMCPPField(this, parent, (ICPPField) binding, true); @@ -1064,11 +1064,6 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return 0; } - @Override - protected boolean cannotAdapt(final IBinding inputBinding) throws CoreException { - return super.cannotAdapt(inputBinding); - } - @Override public final PDOMBinding adaptBinding(final IBinding inputBinding, boolean includeLocal) throws CoreException { return adaptBinding(null, inputBinding, includeLocal ? FILE_LOCAL_REC_DUMMY : null); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java index d79337fe472..ab371778d1b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java @@ -22,7 +22,6 @@ import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.internal.core.dom.parser.IntegralValue; -import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalDeclaredVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.pdom.db.Database; @@ -49,11 +48,6 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable { Database db = getDB(); db.putByte(record + ANNOTATIONS, PDOMCPPAnnotations.encodeVariableAnnotations(variable)); if (setTypeAndValue) { - if (variable instanceof ICPPInternalDeclaredVariable) { - // By the time PDOMCPPVariable is created all declarations and definitions have already been - // added to the variable. - ((ICPPInternalDeclaredVariable) variable).allDeclarationsDefinitionsAdded(); - } setType(parent.getLinkage(), variable.getType()); linkage.new ConfigureVariable(variable, this); }