diff options
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal')
120 files changed, 1541 insertions, 404 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTProblem.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTProblem.java index 92c0d3149d1..5746be46fc1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTProblem.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTProblem.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2016 IBM Corporation and others. + * Copyright (c) 2004, 2020 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -12,9 +12,11 @@ * IBM - Initial API and implementation * Anton Leherbauer (Wind River Systems) * Markus Schorn (Wind River Systems) + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser; +import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; @@ -24,8 +26,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.internal.core.parser.ParserMessages; -import com.ibm.icu.text.MessageFormat; - /** * Models problems, all problems should derive from this class. */ @@ -97,6 +97,8 @@ public class ASTProblem extends ASTNode implements IASTProblem { ParserMessages.getString("ScannerProblemFactory.error.scanner.floatWithBadPrefix")); //$NON-NLS-1$ errorMessages.put(Integer.valueOf(PREPROCESSOR_MULTIPLE_USER_DEFINED_SUFFIXES_IN_CONCATENATION), ParserMessages .getString("ScannerProblemFactory.error.preproc.multipleUserDefinedLiteralSuffixesOnStringLiteral")); //$NON-NLS-1$ + errorMessages.put(Integer.valueOf(PREPROCESSOR_INVALID_USE_OUTSIDE_PREPROCESSOR_DIRECTIVE), + ParserMessages.getString("ScannerProblemFactory.error.preproc.invalidUsageOutsidePreprocDirective")); //$NON-NLS-1$ errorMessages.put(Integer.valueOf(SYNTAX_ERROR), ParserMessages.getString("ParserProblemFactory.error.syntax.syntaxError")); //$NON-NLS-1$ errorMessages.put(Integer.valueOf(MISSING_SEMICOLON), diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java index 1e7b1d279b9..158d2b515c3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java @@ -95,13 +95,13 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat private IBuiltinBindingsProvider fBuiltinBindingsProvider; // Caches - private final ThreadLocal<WeakHashMap<IType, String>> fUnnormalizedTypeStringCache = new ThreadLocal<WeakHashMap<IType, String>>() { + private final ThreadLocal<WeakHashMap<IType, String>> fUnnormalizedTypeStringCache = new ThreadLocal<>() { @Override protected WeakHashMap<IType, String> initialValue() { return new WeakHashMap<>(); } }; - private final ThreadLocal<WeakHashMap<IType, String>> fNormalizedTypeStringCache = new ThreadLocal<WeakHashMap<IType, String>>() { + private final ThreadLocal<WeakHashMap<IType, String>> fNormalizedTypeStringCache = new ThreadLocal<>() { @Override protected WeakHashMap<IType, String> initialValue() { return new WeakHashMap<>(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index 9698bfac8e5..58e28e2f276 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -2816,6 +2816,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { case IGCCToken.t__attribute__: case IGCCToken.tTT_underlying_type: + // msvc-compatibility + case IGCCToken.t__declspec: + // content assist case IToken.tCOMPLETION: return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CStringValue.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CStringValue.java index 6aa59fb0cf2..a8b5ccf245c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CStringValue.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CStringValue.java @@ -251,6 +251,6 @@ public final class CStringValue implements IValue { return false; } CStringValue o = (CStringValue) other; - return fFixedValue.equals(o.fFixedValue); + return CharArrayUtils.equals(fFixedValue, o.fFixedValue); } }
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CompositeValue.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CompositeValue.java index c3192b799f6..4c8a1eb6515 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CompositeValue.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CompositeValue.java @@ -160,7 +160,7 @@ public final class CompositeValue implements IValue { // The set of class types for which composite value creation is in progress on each thread. // Used to guard against infinite recursion due to a class (illegally) aggregating itself. - private static final ThreadLocal<Set<ICPPClassType>> fCreateInProgress = new ThreadLocal<Set<ICPPClassType>>() { + private static final ThreadLocal<Set<ICPPClassType>> fCreateInProgress = new ThreadLocal<>() { @Override protected Set<ICPPClassType> initialValue() { return new TreeSet<>((type1, type2) -> { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/FloatingPointValue.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/FloatingPointValue.java index a0837864035..cb233077d38 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/FloatingPointValue.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/FloatingPointValue.java @@ -182,6 +182,6 @@ public final class FloatingPointValue implements IValue { return false; } FloatingPointValue o = (FloatingPointValue) other; - return fFixedValue.equals(o.fFixedValue); + return CharArrayUtils.equals(fFixedValue, o.fFixedValue); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java index bf2469eb5f9..407c02e1d05 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java @@ -53,6 +53,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitTypedef; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecBuiltin; /** * This is the IBuiltinBindingsProvider used to implement the "Other" built-in GCC symbols defined: @@ -188,9 +190,25 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { function("bool", "__atomic_always_lock_free", "size_t", "void*"); function("bool", "__atomic_is_lock_free", "size_t", "void*"); + ICPPExecution builtinFfs = new ExecBuiltin(ExecBuiltin.BUILTIN_FFS); + ICPPExecution builtinFfsl = new ExecBuiltin(ExecBuiltin.BUILTIN_FFSL); + ICPPExecution builtinFfsll = new ExecBuiltin(ExecBuiltin.BUILTIN_FFSLL); + ICPPExecution builtinCtz = new ExecBuiltin(ExecBuiltin.BUILTIN_CTZ); + ICPPExecution builtinCtzl = new ExecBuiltin(ExecBuiltin.BUILTIN_CTZL); + ICPPExecution builtinCtzll = new ExecBuiltin(ExecBuiltin.BUILTIN_CTZLL); + ICPPExecution builtinPopcount = new ExecBuiltin(ExecBuiltin.BUILTIN_POPCOUNT); + ICPPExecution builtinPopcountl = new ExecBuiltin(ExecBuiltin.BUILTIN_POPCOUNTL); + ICPPExecution builtinPopcountll = new ExecBuiltin(ExecBuiltin.BUILTIN_POPCOUNTLL); + ICPPExecution builtinParity = new ExecBuiltin(ExecBuiltin.BUILTIN_PARITY); + ICPPExecution builtinParityl = new ExecBuiltin(ExecBuiltin.BUILTIN_PARITYL); + ICPPExecution builtinParityll = new ExecBuiltin(ExecBuiltin.BUILTIN_PARITYLL); + ICPPExecution builtinAbs = new ExecBuiltin(ExecBuiltin.BUILTIN_ABS); + ICPPExecution builtinLabs = new ExecBuiltin(ExecBuiltin.BUILTIN_LABS); + ICPPExecution builtinLlabs = new ExecBuiltin(ExecBuiltin.BUILTIN_LLABS); + // Other Builtins (https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html) [incomplete] function("void", "__builtin_abort"); - function("int", "__builtin_abs", "int"); + function("int", "__builtin_abs", builtinAbs, "int"); function("double", "__builtin_acos", "double"); function("float", "__builtin_acosf", "float"); function("long double", "__builtin_acosl", "long double"); @@ -224,6 +242,10 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { function("double", "__builtin_cimag", "complex double"); function("float", "__builtin_cimagf", "complex float"); function("long double", "__builtin_cimagl", "complex long double"); + function("void", "__builtin___clear_cache", "void*", "void*"); + function("int", "__builtin_clrsb", "int"); + function("int", "__builtin_clrsbl", "long"); + function("int", "__builtin_clrsbll", "long long"); function("int", "__builtin_clz", "unsigned int"); function("int", "__builtin_clzl", "unsigned long"); function("int", "__builtin_clzll", "unsigned long long"); @@ -243,9 +265,9 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { function("double", "__builtin_creal", "complex double"); function("float", "__builtin_crealf", "complex float"); function("long double", "__builtin_creall", "complex long double"); - function("int", "__builtin_ctz", "unsigned int"); - function("int", "__builtin_ctzl", "unsigned long"); - function("int", "__builtin_ctzll", "unsigned long long"); + function("int", "__builtin_ctz", builtinCtz, "unsigned int"); + function("int", "__builtin_ctzl", builtinCtzl, "unsigned long"); + function("int", "__builtin_ctzll", builtinCtzll, "unsigned long long"); function("double", "__builtin_erf", "double"); function("float", "__builtin_erff", "float"); function("long double", "__builtin_erfl", "long double"); @@ -265,15 +287,17 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { function("float", "__builtin_expm1f", "float"); function("long double", "__builtin_expm1l", "long double"); function("long", "__builtin_expect", "long", "long"); + function("long", "__builtin_expect_with_probability", "long", "long", "double"); + function("unsigned long long int", "__builtin_extend_pointer", "void*"); function("double", "__builtin_fabs", "double"); function("float", "__builtin_fabsf", "float"); function("long double", "__builtin_fabsl", "long double"); function("double", "__builtin_fdim", "double", "double"); function("float", "__builtin_fdimf", "float", "float"); function("long double", "__builtin_fdiml", "long double", "long double"); - function("int", "__builtin_ffs", "unsigned int"); - function("int", "__builtin_ffsl", "unsigned long"); - function("int", "__builtin_ffsll", "unsigned long long"); + function("int", "__builtin_ffs", builtinFfs, "unsigned int"); + function("int", "__builtin_ffsl", builtinFfsl, "unsigned long"); + function("int", "__builtin_ffsll", builtinFfsll, "unsigned long long"); function("double", "__builtin_floor", "double"); function("float", "__builtin_floorf", "float"); function("long double", "__builtin_floorl", "long double"); @@ -295,6 +319,8 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { function("double", "__builtin_frexp", "double", "int*"); function("float", "__builtin_frexpf", "float", "int*"); function("long double", "__builtin_frexpl", "long double", "int*"); + function("int", "__builtin_goacc_parlevel_id", "int"); + function("int", "__builtin_goacc_parlevel_size", "int"); function("double", "__builtin_huge_val"); function("float", "__builtin_huge_valf"); function("long double", "__builtin_huge_vall"); @@ -306,8 +332,12 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { function("int", "__builtin_ilogbl", "long double"); function("long long", "__builtin_imaxabs", "long long"); function("double", "__builtin_inf"); + function("_Decimal32", "__builtin_infd32"); + function("_Decimal64", "__builtin_infd64"); + function("_Decimal128", "__builtin_infd128"); function("float", "__builtin_inff"); function("long double", "__builtin_infl"); + function("int", "__builtin_isinf_sign", "..."); function("bool", "__builtin_isfinite", "double"); function("bool", "__builtin_isgreater", "float", "float"); function("bool", "__builtin_isgreaterequal", "float", "float"); @@ -318,14 +348,17 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { function("bool", "__builtin_isnan", "double"); function("bool", "__builtin_isnormal", "double"); function("bool", "__builtin_isunordered", "float", "float"); - function("long", "__builtin_labs", "long"); + function("long", "__builtin_labs", builtinLabs, "long"); function("double", "__builtin_ldexp", "double", "int"); function("float", "__builtin_ldexpf", "float", "int"); function("long double", "__builtin_ldexpl", "long double", "int"); function("double", "__builtin_lgamma", "double"); function("float", "__builtin_lgammaf", "float"); function("long double", "__builtin_lgammal", "long double"); - function("long long", "__builtin_llabs", "long long"); + function("int", "__builtin_LINE"); //TODO: This should technically be a constant integer expression + function("const char *", "__builtin_FUNCTION"); + function("const char *", "__builtin_FILE"); + function("long long", "__builtin_llabs", builtinLlabs, "long long"); function("long long", "__builtin_llrint", "double"); function("long long", "__builtin_llrintf", "float"); function("long long", "__builtin_llrintl", "long double"); @@ -361,6 +394,9 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { function("void*", "__builtin_memmove", "void*", "const void*", "size_t"); // not in the manual function("void*", "__builtin_memset", "void*", "int", "size_t"); function("double", "__builtin_nan", "const char*"); + function("_Decimal32", "__builtin_nand32"); + function("_Decimal64", "__builtin_nand64"); + function("_Decimal128", "__builtin_nand128"); function("float", "__builtin_nanf", "const char*"); function("long double", "__builtin_nanl", "const char*"); function("double", "__builtin_nans", "const char*"); @@ -375,12 +411,12 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { function("double", "__builtin_nexttoward", "double", "long double"); function("float", "__builtin_nexttowardf", "float", "long double"); function("long double", "__builtin_nexttowardl", "long double", "long double"); - function("int", "__builtin_parity", "unsigned int"); - function("int", "__builtin_parityl", "unsigned long"); - function("int", "__builtin_parityll", "unsigned long long"); - function("int", "__builtin_popcount", "unsigned int"); - function("int", "__builtin_popcountl", "unsigned long"); - function("int", "__builtin_popcountll", "unsigned long long"); + function("int", "__builtin_parity", builtinParity, "unsigned int"); + function("int", "__builtin_parityl", builtinParityl, "unsigned long"); + function("int", "__builtin_parityll", builtinParityll, "unsigned long long"); + function("int", "__builtin_popcount", builtinPopcount, "unsigned int"); + function("int", "__builtin_popcountl", builtinPopcountl, "unsigned long"); + function("int", "__builtin_popcountll", builtinPopcountll, "unsigned long long"); function("double", "__builtin_pow", "double", "double"); function("float", "__builtin_powf", "float", "float"); function("long double", "__builtin_powl", "long double", "long double"); @@ -445,10 +481,12 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { function("double", "__builtin_tgamma", "double"); function("float", "__builtin_tgammaf", "float"); function("long double", "__builtin_tgammal", "long double"); + function("void", "__builtin_trap"); function("double", "__builtin_trunc", "double"); function("float", "__builtin_truncf", "float"); function("long double", "__builtin_truncl", "long double"); function("int", "__builtin_types_compatible_p", "", ""); + function("void", "__builtin_unreachable"); function("int", "__builtin_vprintf", "const char*", "va_list"); function("int", "__builtin_vscanf", "const char*", "va_list"); function("int", "__builtin_vsnprintf", "char*", "size_t", "const char*", "va_list"); @@ -481,6 +519,13 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { } private void function(String returnType, String name, String... parameterTypes) { + function(returnType, name, null, parameterTypes); + } + + /* + * Create a function which can possibly be constexpr-evaluated + */ + private void function(String returnType, String name, ICPPExecution exec, String... parameterTypes) { int len = parameterTypes.length; boolean varargs = len > 0 && parameterTypes[len - 1].equals("..."); if (varargs) @@ -491,14 +536,14 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { for (int i = 0; i < len; i++) { IType pType = toType(parameterTypes[i]); pTypes[i] = pType; - theParms[i] = fCpp ? new CPPBuiltinParameter(pType) : new CBuiltinParameter(pType); + theParms[i] = fCpp ? new CPPBuiltinParameter(pType, i) : new CBuiltinParameter(pType); } IType rt = toType(returnType); IFunctionType ft = fCpp ? new CPPFunctionType(rt, pTypes, null) : new CFunctionType(rt, pTypes); IBinding b = fCpp - ? new CPPImplicitFunction(toCharArray(name), fScope, (ICPPFunctionType) ft, (ICPPParameter[]) theParms, - false, varargs) + ? new CPPBuiltinImplicitFunction(toCharArray(name), fScope, (ICPPFunctionType) ft, + (ICPPParameter[]) theParms, varargs, exec) : new CImplicitFunction(toCharArray(name), fScope, ft, theParms, varargs); fBindingList.add(b); } @@ -591,6 +636,15 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { } else if (tstr.equals("char")) { Kind kind = Kind.eChar; t = fCpp ? new CPPBasicType(kind, q) : new CBasicType(kind, q); + } else if (tstr.equals("_Decimal32")) { + Kind kind = Kind.eDecimal32; + t = fCpp ? new CPPBasicType(kind, q) : new CBasicType(kind, q); + } else if (tstr.equals("_Decimal64")) { + Kind kind = Kind.eDecimal64; + t = fCpp ? new CPPBasicType(kind, q) : new CBasicType(kind, q); + } else if (tstr.equals("_Decimal128")) { + Kind kind = Kind.eDecimal128; + t = fCpp ? new CPPBasicType(kind, q) : new CBasicType(kind, q); } else if (tstr.equals("int")) { Kind kind = Kind.eInt; t = fCpp ? new CPPBasicType(kind, q) : new CBasicType(kind, q); @@ -632,4 +686,22 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider { public boolean isKnownBuiltin(char[] builtinName) { return fKnownBuiltins.containsKey(builtinName); } + + /* + * A builtin function which can be evaluated in a constexpr context + */ + private static class CPPBuiltinImplicitFunction extends CPPImplicitFunction { + private ICPPExecution execution; + + public CPPBuiltinImplicitFunction(char[] name, IScope scope, ICPPFunctionType type, ICPPParameter[] params, + boolean takesVarArgs, ICPPExecution execution) { + super(name, scope, type, params, true, takesVarArgs); + this.execution = execution; + } + + @Override + public ICPPExecution getFunctionBodyExecution() { + return execution; + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java index cc215747ed2..b7e352d7bf1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java @@ -52,7 +52,7 @@ public interface ITypeMarshalBuffer { EXEC_DECLARATION_STATEMENT = 0x05, EXEC_DECLARATOR = 0x06, EXEC_DEFAULT = 0x07, EXEC_SIMPLE_DECLARATION = 0x08, EXEC_RETURN = 0x09, EXEC_EXPRESSION_STATEMENT = 0x0A, EXEC_IF = 0x0B, EXEC_WHILE = 0x0C, EXEC_DO = 0x0D, EXEC_FOR = 0x0E, EXEC_RANGE_BASED_FOR = 0x0F, EXEC_SWITCH = 0x10, - EXEC_CONSTRUCTOR_CHAIN = 0x11, EXEC_INCOMPLETE = 0x12; + EXEC_CONSTRUCTOR_CHAIN = 0x11, EXEC_INCOMPLETE = 0x12, EXEC_BUILTIN = 0x13; // Can add more executions up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE. static final short KIND_MASK = 0x001F; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IntegralValue.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IntegralValue.java index 1cf9d4f822b..4487599727f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IntegralValue.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IntegralValue.java @@ -297,6 +297,6 @@ public class IntegralValue implements IValue { return false; } IntegralValue o = (IntegralValue) other; - return fFixedValue.equals(o.fFixedValue); + return CharArrayUtils.equals(fFixedValue, o.fFixedValue); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java index 6c2498d59e1..2b7e6f28e83 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2015 IBM Corporation and others. + * Copyright (c) 2004, 2020 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -13,9 +13,12 @@ * Markus Schorn (Wind River Systems) * Bryan Wilkinson (QNX) * Sergey Prigogin (Google) + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser; +import java.text.MessageFormat; + import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -40,8 +43,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.parser.ParserMessages; import org.eclipse.core.runtime.PlatformObject; -import com.ibm.icu.text.MessageFormat; - /** * Implementation of problem bindings */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java index 9d104b03465..68651b83224 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java @@ -603,6 +603,11 @@ public class ValueFactory { return IntegralValue.create(1); } return IntegralValue.create(0); + case __is_same: + if (type1.isSameType(type2)) { + return IntegralValue.create(1); + } + return IntegralValue.create(0); case __is_trivially_assignable: return IntegralValue.UNKNOWN; // TODO: Implement. } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java index fb757d85f89..594a4240d0d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java @@ -14,6 +14,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser; +import java.util.Optional; + import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; @@ -21,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDoStatement; import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; @@ -56,6 +59,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTStructuredBindingDeclaration; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; +import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; /** @@ -67,7 +71,19 @@ public abstract class VariableReadWriteFlags { protected static final int READ = PDOMName.READ_ACCESS; protected static final int WRITE = PDOMName.WRITE_ACCESS; - protected int rwAnyNode(IASTNode node, int indirection) { + /** + * Check if the access could be a write access taking into + * account the "unknown" state. + * @param flags The flags + * @return True if either write or unknown access detected, false otherwise + */ + public static boolean mayBeWriteAccess(Optional<Integer> flags) { + if (!flags.isPresent() || (flags.get() & WRITE) != 0) + return true; + return false; + } + + protected Optional<Integer> rwAnyNode(IASTNode node, int indirection) { final IASTNode parent = node.getParent(); if (parent instanceof IASTExpression) { return rwInExpression((IASTExpression) parent, node, indirection); @@ -78,20 +94,22 @@ public abstract class VariableReadWriteFlags { } else if (parent instanceof IASTEqualsInitializer) { return rwInEqualsInitializer((IASTEqualsInitializer) parent, indirection); } else if (parent instanceof IASTArrayModifier) { - return READ; // dimension + return Optional.of(READ); // dimension } else if (parent instanceof IASTInitializerList) { return rwInInitializerList((IASTInitializerList) parent, indirection); + } else if (parent instanceof IASTDeclSpecifier) { + return Optional.of(READ); } - return READ | WRITE; // fallback + return Optional.empty(); // fallback } - protected int rwInDeclarator(IASTDeclarator parent, int indirection) { + protected Optional<Integer> rwInDeclarator(IASTDeclarator parent, int indirection) { if (parent.getInitializer() != null) - return WRITE; - return 0; + return Optional.of(WRITE); + return Optional.of(0); } - protected int rwInEqualsInitializer(IASTEqualsInitializer parent, int indirection) { + protected Optional<Integer> rwInEqualsInitializer(IASTEqualsInitializer parent, int indirection) { IASTNode grand = parent.getParent(); if (grand instanceof IASTDeclarator) { IBinding binding = ((IASTDeclarator) grand).getName().getBinding(); @@ -101,10 +119,10 @@ public abstract class VariableReadWriteFlags { } else if (grand instanceof ICPPASTStructuredBindingDeclaration) { return rwInStructuredBinding((ICPPASTStructuredBindingDeclaration) grand); } - return READ | WRITE; // fallback + return Optional.empty(); // fallback } - protected int rwInInitializerList(IASTInitializerList parent, int indirection) { + protected Optional<Integer> rwInInitializerList(IASTInitializerList parent, int indirection) { IASTNode grand = parent.getParent(); if (grand instanceof IASTEqualsInitializer) { IASTNode grandGrand = grand.getParent(); @@ -120,19 +138,37 @@ public abstract class VariableReadWriteFlags { } else if (grand instanceof ICPPASTStructuredBindingDeclaration) { return rwInStructuredBinding((ICPPASTStructuredBindingDeclaration) grand); } - return READ | WRITE; // fallback + return Optional.empty(); // fallback } - protected int rwInStructuredBinding(ICPPASTStructuredBindingDeclaration declaration) { + protected Optional<Integer> rwInStructuredBinding(ICPPASTStructuredBindingDeclaration declaration) { RefQualifier refQualifier = declaration.getRefQualifier(); if (refQualifier != null && !declaration.getDeclSpecifier().isConst()) { - return READ | WRITE; + return Optional.of(READ | WRITE); } else { - return READ; + return Optional.of(READ); + } + } + + private boolean isAssignment(IASTBinaryExpression node) { + switch (node.getOperator()) { + case IASTBinaryExpression.op_assign: + case IASTBinaryExpression.op_binaryAndAssign: + case IASTBinaryExpression.op_binaryOrAssign: + case IASTBinaryExpression.op_binaryXorAssign: + case IASTBinaryExpression.op_divideAssign: + case IASTBinaryExpression.op_minusAssign: + case IASTBinaryExpression.op_moduloAssign: + case IASTBinaryExpression.op_multiplyAssign: + case IASTBinaryExpression.op_plusAssign: + case IASTBinaryExpression.op_shiftLeftAssign: + case IASTBinaryExpression.op_shiftRightAssign: + return true; } + return false; } - protected int rwInExpression(IASTExpression expr, IASTNode node, int indirection) { + protected Optional<Integer> rwInExpression(IASTExpression expr, IASTNode node, int indirection) { if (expr instanceof IASTIdExpression) { return rwAnyNode(expr, indirection); } @@ -152,11 +188,16 @@ public abstract class VariableReadWriteFlags { if (indirection > 0 && node.getPropertyInParent() == IASTArraySubscriptExpression.ARRAY) { return rwAnyNode(expr, indirection - 1); } - return READ; + if (expr.getParent() instanceof IASTBinaryExpression + && expr.getPropertyInParent() == IASTBinaryExpression.OPERAND_ONE + && isAssignment((IASTBinaryExpression) expr.getParent())) { + return Optional.of(READ | WRITE); + } + return Optional.of(READ); } if (expr instanceof IASTConditionalExpression) { if (node.getPropertyInParent() == IASTConditionalExpression.LOGICAL_CONDITION) { - return READ; + return Optional.of(READ); } return rwAnyNode(expr, indirection); } @@ -166,7 +207,7 @@ public abstract class VariableReadWriteFlags { if (expressions.length > 0 && expressions[0] == node) { return rwAnyNode(expr, indirection); } - return 0; + return Optional.of(0); } if (expr instanceof IASTFunctionCallExpression) { if (node.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) { @@ -175,16 +216,16 @@ public abstract class VariableReadWriteFlags { return rwArgumentForFunctionCall((IASTFunctionCallExpression) expr, node, indirection); } if (expr instanceof IASTProblemExpression) { - return READ | WRITE; + return Optional.of(READ | WRITE); } if (expr instanceof IASTTypeIdExpression) { - return 0; + return Optional.of(0); } - return READ | WRITE; // fall back + return Optional.empty(); // fall back } - protected int rwInFieldReference(IASTNode node, IASTFieldReference expr, int indirection) { + protected Optional<Integer> rwInFieldReference(IASTNode node, IASTFieldReference expr, int indirection) { if (node.getPropertyInParent() == IASTFieldReference.FIELD_NAME) { if (expr.getPropertyInParent() != IASTFunctionCallExpression.FUNCTION_NAME) return rwAnyNode(expr, indirection); @@ -194,39 +235,55 @@ public abstract class VariableReadWriteFlags { if (indirection >= 0) return rwAnyNode(expr, indirection); } - return READ; + return Optional.of(READ); } - protected int rwInFunctionName(IASTExpression node) { - return READ; + protected Optional<Integer> rwInFunctionName(IASTExpression node) { + return Optional.of(READ); } - protected int rwArgumentForFunctionCall(final IASTFunctionCallExpression funcCall, IASTNode argument, + /** + * Helper method to take the union of two sets of read/write flags. + * Note that "unknown" (represented as Optional.empty()) unioned + * with anything is still "unknown", since "unknown" means that + * potentially any type of access is possible. + */ + protected Optional<Integer> union(Optional<Integer> a, Optional<Integer> b) { + if (a.isPresent() && b.isPresent()) { + return Optional.of(a.get() | b.get()); + } + return Optional.empty(); + } + + protected Optional<Integer> rwArgumentForFunctionCall(final IASTFunctionCallExpression funcCall, IASTNode argument, int indirection) { final IASTInitializerClause[] args = funcCall.getArguments(); - for (int i = 0; i < args.length; i++) { - if (args[i] == argument) { - final IASTExpression functionNameExpression = funcCall.getFunctionNameExpression(); - if (functionNameExpression != null) { - final IType type = functionNameExpression.getExpressionType(); - if (type instanceof IFunctionType) { - return rwArgumentForFunctionCall((IFunctionType) type, i, args[i], indirection); - } else if (funcCall instanceof IASTImplicitNameOwner) { - IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) funcCall).getImplicitNames(); - if (implicitNames.length == 1) { - IASTImplicitName name = implicitNames[0]; - IBinding binding = name.resolveBinding(); - if (binding instanceof IFunction) { - return rwArgumentForFunctionCall(((IFunction) binding).getType(), i, args[i], - indirection); - } - } - } + int index = ArrayUtil.indexOf(args, argument); + if (index == -1) { + return Optional.empty(); + } + final IASTExpression functionNameExpression = funcCall.getFunctionNameExpression(); + if (functionNameExpression == null) { + return Optional.empty(); + } + IType type = functionNameExpression.getExpressionType(); + IFunctionType functionType = null; + if (type instanceof IFunctionType) { + functionType = (IFunctionType) type; + } else if (funcCall instanceof IASTImplicitNameOwner) { + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) funcCall).getImplicitNames(); + if (implicitNames.length == 1) { + IASTImplicitName name = implicitNames[0]; + IBinding binding = name.resolveBinding(); + if (binding instanceof IFunction) { + functionType = ((IFunction) binding).getType(); } - break; } } - return READ | WRITE; // Fallback + if (functionType == null) { + return Optional.empty(); + } + return rwArgumentForFunctionCall(functionType, index, args[index], indirection); } private IType getArgumentType(IASTInitializerClause argument) { @@ -238,8 +295,8 @@ public abstract class VariableReadWriteFlags { return null; } - protected int rwArgumentForFunctionCall(IFunctionType type, int parameterIdx, IASTInitializerClause argument, - int indirection) { + protected Optional<Integer> rwArgumentForFunctionCall(IFunctionType type, int parameterIdx, + IASTInitializerClause argument, int indirection) { IType[] ptypes = type.getParameterTypes(); IType parameterType = null; if (ptypes != null && ptypes.length > parameterIdx) { @@ -253,19 +310,19 @@ public abstract class VariableReadWriteFlags { if (parameterType != null) { return rwAssignmentToType(parameterType, indirection); } - return READ | WRITE; // Fallback + return Optional.empty(); // Fallback } - protected abstract int rwAssignmentToType(IType type, int indirection); + protected abstract Optional<Integer> rwAssignmentToType(IType type, int indirection); - protected int rwInStatement(IASTStatement stmt, IASTNode node, int indirection) { + protected Optional<Integer> rwInStatement(IASTStatement stmt, IASTNode node, int indirection) { if (stmt instanceof IASTCaseStatement) { if (node.getPropertyInParent() == IASTCaseStatement.EXPRESSION) { - return READ; + return Optional.of(READ); } } else if (stmt instanceof IASTDoStatement) { if (node.getPropertyInParent() == IASTDoStatement.CONDITION) { - return READ; + return Optional.of(READ); } } else if (stmt instanceof IASTExpressionStatement) { IASTNode parent = stmt.getParent(); @@ -273,7 +330,7 @@ public abstract class VariableReadWriteFlags { IASTCompoundStatement compound = (IASTCompoundStatement) parent; IASTStatement[] statements = compound.getStatements(); if (statements[statements.length - 1] != stmt) { - return 0; + return Optional.of(0); } stmt = compound; parent = stmt.getParent(); @@ -283,33 +340,33 @@ public abstract class VariableReadWriteFlags { } } else if (stmt instanceof IASTForStatement) { if (node.getPropertyInParent() == IASTForStatement.CONDITION) { - return READ; + return Optional.of(READ); } } else if (stmt instanceof ICPPASTRangeBasedForStatement) { if (node.getPropertyInParent() == ICPPASTRangeBasedForStatement.INITIALIZER) { - return READ; + return Optional.of(READ); } } else if (stmt instanceof IASTIfStatement) { if (node.getPropertyInParent() == IASTIfStatement.CONDITION) { - return READ; + return Optional.of(READ); } } else if (stmt instanceof IASTProblemStatement) { - return READ | WRITE; + return Optional.empty(); } else if (stmt instanceof IASTReturnStatement) { - return indirection == 0 ? READ : WRITE; + return indirection == 0 ? Optional.of(READ) : Optional.of(WRITE); } else if (stmt instanceof IASTSwitchStatement) { if (node.getPropertyInParent() == IASTSwitchStatement.CONTROLLER_EXP) { - return READ; + return Optional.of(READ); } } else if (stmt instanceof IASTWhileStatement) { if (node.getPropertyInParent() == IASTWhileStatement.CONDITIONEXPRESSION) { - return READ; + return Optional.of(READ); } } - return 0; + return Optional.of(0); } - protected int rwInUnaryExpression(IASTNode node, IASTUnaryExpression expr, int indirection) { + protected Optional<Integer> rwInUnaryExpression(IASTNode node, IASTUnaryExpression expr, int indirection) { switch (expr.getOperator()) { case IASTUnaryExpression.op_bracketedPrimary: return rwAnyNode(expr, indirection); @@ -321,33 +378,33 @@ public abstract class VariableReadWriteFlags { if (indirection > 0) { return rwAnyNode(expr, indirection - 1); } - return READ; + return Optional.of(READ); case IASTUnaryExpression.op_postFixDecr: case IASTUnaryExpression.op_postFixIncr: case IASTUnaryExpression.op_prefixDecr: case IASTUnaryExpression.op_prefixIncr: - return READ | WRITE; + return Optional.of(READ | WRITE); case IASTUnaryExpression.op_minus: case IASTUnaryExpression.op_not: case IASTUnaryExpression.op_plus: case IASTUnaryExpression.op_tilde: - return PDOMName.READ_ACCESS; + return Optional.of(READ); case IASTUnaryExpression.op_sizeof: case IASTUnaryExpression.op_sizeofParameterPack: case IASTUnaryExpression.op_alignOf: - return 0; + return Optional.of(0); } - return READ; + return Optional.of(READ); } - protected int rwInBinaryExpression(IASTNode node, IASTBinaryExpression expr, int indirection) { + protected Optional<Integer> rwInBinaryExpression(IASTNode node, IASTBinaryExpression expr, int indirection) { switch (expr.getOperator()) { case IASTBinaryExpression.op_assign: if (node.getPropertyInParent() == IASTBinaryExpression.OPERAND_ONE) { - return WRITE; + return Optional.of(WRITE); } return rwAssignmentToType(expr.getOperand1().getExpressionType(), indirection); @@ -362,9 +419,9 @@ public abstract class VariableReadWriteFlags { case IASTBinaryExpression.op_shiftLeftAssign: case IASTBinaryExpression.op_shiftRightAssign: if (node.getPropertyInParent() == IASTBinaryExpression.OPERAND_ONE) { - return READ | WRITE; + return Optional.of(READ | WRITE); } - return READ; + return Optional.of(READ); case IASTBinaryExpression.op_binaryAnd: case IASTBinaryExpression.op_binaryOr: @@ -382,7 +439,7 @@ public abstract class VariableReadWriteFlags { case IASTBinaryExpression.op_notequals: case IASTBinaryExpression.op_shiftLeft: case IASTBinaryExpression.op_shiftRight: - return READ; + return Optional.of(READ); case IASTBinaryExpression.op_minus: case IASTBinaryExpression.op_plus: @@ -390,8 +447,8 @@ public abstract class VariableReadWriteFlags { // can be pointer arithmetics return rwAnyNode(expr, indirection); } - return READ; + return Optional.of(READ); } - return READ; // fallback + return Optional.of(READ); // fallback } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java index 6fb435ef8d4..43f0e086f01 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java @@ -97,9 +97,6 @@ public class CEnumeration extends PlatformObject implements IEnumeration, ICInte return; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() - */ @Override public String getName() { if (definition != null) @@ -116,9 +113,6 @@ public class CEnumeration extends PlatformObject implements IEnumeration, ICInte return declarations[0].toCharArray(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() - */ @Override public IScope getScope() { return CVisitor.getContainingScope(definition != null ? definition : declarations[0].getParent()); @@ -135,9 +129,6 @@ public class CEnumeration extends PlatformObject implements IEnumeration, ICInte return t; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IEnumeration#getEnumerators() - */ @Override public IEnumerator[] getEnumerators() { if (definition == null) { @@ -162,9 +153,6 @@ public class CEnumeration extends PlatformObject implements IEnumeration, ICInte definition = name; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) - */ @Override public boolean isSameType(IType type) { if (type == this) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumerator.java index ab2fc1c9155..25048ec8e20 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumerator.java @@ -56,9 +56,6 @@ public class CEnumerator extends PlatformObject implements IEnumerator { return enumeratorName; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() - */ @Override public String getName() { return enumeratorName.toString(); @@ -69,17 +66,11 @@ public class CEnumerator extends PlatformObject implements IEnumerator { return enumeratorName.toCharArray(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() - */ @Override public IScope getScope() { return CVisitor.getContainingScope(enumeratorName.getParent()); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IEnumerator#getType() - */ @Override public IType getType() { return (IType) getOwner(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java index 6fb3529f223..6a4e6f842e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java @@ -496,6 +496,12 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu return dtor != null && AttributeUtil.hasNoreturnAttribute(dtor); } + @Override + public boolean isNoDiscard() { + IASTFunctionDeclarator dtor = getPreferredDtor(); + return dtor != null && AttributeUtil.hasNodiscardAttribute(dtor); + } + protected IASTFunctionDeclarator getPreferredDtor() { IASTFunctionDeclarator dtor = getDefinition(); if (dtor != null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunctionScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunctionScope.java index 1d914d061d5..d3c51249bed 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunctionScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunctionScope.java @@ -27,9 +27,6 @@ public class CFunctionScope extends CScope implements ICFunctionScope { super(function, EScopeKind.eLocal); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.c.ICFunctionScope#getBinding(char[]) - */ @Override public IBinding getBinding(char[] name) { return super.getBinding(NAMESPACE_TYPE_OTHER, name); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitTypedef.java index 34af4fe7c4f..685f9a85cc1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitTypedef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitTypedef.java @@ -57,9 +57,6 @@ public class CImplicitTypedef extends CTypedef { return scope; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) - */ // public boolean isSameType(IType t) { // if (t == this) // return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CKnRParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CKnRParameter.java index 92285332ead..f37a41f34d1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CKnRParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CKnRParameter.java @@ -42,9 +42,6 @@ public class CKnRParameter extends PlatformObject implements IParameter { this.name = name; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IVariable#getType() - */ @Override public IType getType() { IASTDeclSpecifier declSpec = null; @@ -62,56 +59,35 @@ public class CKnRParameter extends PlatformObject implements IParameter { return null; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() - */ @Override public String getName() { return name.toString(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() - */ @Override public char[] getNameCharArray() { return name.toCharArray(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() - */ @Override public IScope getScope() { return CVisitor.getContainingScope(declaration); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode() - */ public IASTNode getPhysicalNode() { return declaration; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic() - */ @Override public boolean isStatic() { return false; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IVariable#isExtern() - */ @Override public boolean isExtern() { return false; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IVariable#isAuto() - */ @Override public boolean isAuto() { if (declaration instanceof IASTSimpleDeclaration) @@ -120,9 +96,6 @@ public class CKnRParameter extends PlatformObject implements IParameter { return false; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IVariable#isRegister() - */ @Override public boolean isRegister() { if (declaration instanceof IASTSimpleDeclaration) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java index 3b1a526fc78..80d15a39748 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java @@ -68,25 +68,16 @@ public class CQualifierType implements ICQualifierType, ITypeContainer, ISeriali return false; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IQualifierType#isConst() - */ @Override public boolean isConst() { return isConst; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IQualifierType#isVolatile() - */ @Override public boolean isVolatile() { return isVolatile; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.c.ICQualifierType#isRestrict() - */ @Override public boolean isRestrict() { return isRestrict; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java index 576190d1363..6314292ed60 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java @@ -51,7 +51,7 @@ public class CVariable extends PlatformObject implements ICInternalBinding, IVar * The set of CVariable objects for which initial value computation is in progress on each thread. * This is used to guard against recursion during initial value computation. */ - private static final ThreadLocal<Set<CVariable>> fInitialValueInProgress = new ThreadLocal<Set<CVariable>>() { + private static final ThreadLocal<Set<CVariable>> fInitialValueInProgress = new ThreadLocal<>() { @Override protected Set<CVariable> initialValue() { return new HashSet<>(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariableReadWriteFlags.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariableReadWriteFlags.java index 62f8baa7a67..398bbb44eef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariableReadWriteFlags.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariableReadWriteFlags.java @@ -13,6 +13,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; +import java.util.Optional; + import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; @@ -33,47 +35,48 @@ import org.eclipse.cdt.internal.core.dom.parser.VariableReadWriteFlags; public final class CVariableReadWriteFlags extends VariableReadWriteFlags { private static CVariableReadWriteFlags INSTANCE = new CVariableReadWriteFlags(); - public static int getReadWriteFlags(IASTName variable) { + public static Optional<Integer> getReadWriteFlags(IASTName variable) { return INSTANCE.rwAnyNode(variable, 0); } @Override - protected int rwAnyNode(IASTNode node, int indirection) { + protected Optional<Integer> rwAnyNode(IASTNode node, int indirection) { final IASTNode parent = node.getParent(); if (parent instanceof ICASTFieldDesignator) { - return WRITE; // node is initialized via designated initializer + return Optional.of(WRITE); // node is initialized via designated initializer } return super.rwAnyNode(node, indirection); } @Override - protected int rwInExpression(IASTExpression expr, IASTNode node, int indirection) { + protected Optional<Integer> rwInExpression(IASTExpression expr, IASTNode node, int indirection) { if (expr instanceof ICASTTypeIdInitializerExpression) { - return 0; + return Optional.of(0); } return super.rwInExpression(expr, node, indirection); } @Override - protected int rwInEqualsInitializer(IASTEqualsInitializer parent, int indirection) { + protected Optional<Integer> rwInEqualsInitializer(IASTEqualsInitializer parent, int indirection) { if (indirection == 0) { - return READ; + return Optional.of(READ); } return super.rwInEqualsInitializer(parent, indirection); } @Override - protected int rwArgumentForFunctionCall(IASTFunctionCallExpression funcCall, IASTNode argument, int indirection) { + protected Optional<Integer> rwArgumentForFunctionCall(IASTFunctionCallExpression funcCall, IASTNode argument, + int indirection) { if (indirection == 0) { - return READ; + return Optional.of(READ); } return super.rwArgumentForFunctionCall(funcCall, argument, indirection); } @Override - protected int rwAssignmentToType(IType type, int indirection) { + protected Optional<Integer> rwAssignmentToType(IType type, int indirection) { if (indirection == 0) { - return READ; + return Optional.of(READ); } while (indirection > 0 && (type instanceof IPointerType)) { type = ((IPointerType) type).getType(); @@ -81,11 +84,11 @@ public final class CVariableReadWriteFlags extends VariableReadWriteFlags { } if (indirection == 0) { if (type instanceof IQualifierType) { - return ((IQualifierType) type).isConst() ? READ : READ | WRITE; + return ((IQualifierType) type).isConst() ? Optional.of(READ) : Optional.of(READ | WRITE); } else if (type instanceof IPointerType) { - return ((IPointerType) type).isConst() ? READ : READ | WRITE; + return ((IPointerType) type).isConst() ? Optional.of(READ) : Optional.of(READ | WRITE); } } - return READ | WRITE; // fallback + return Optional.empty(); // Fallback } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index cfd4de9336d..1f59167c318 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -174,9 +174,6 @@ public class CVisitor extends ASTQueries { return removeNullFromProblems(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration) - */ @Override public int visit(IASTDeclaration declaration) { if (declaration instanceof IASTProblemHolder) @@ -185,9 +182,6 @@ public class CVisitor extends ASTQueries { return PROCESS_CONTINUE; } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression) - */ @Override public int visit(IASTExpression expression) { if (expression instanceof IASTProblemHolder) @@ -196,9 +190,6 @@ public class CVisitor extends ASTQueries { return PROCESS_CONTINUE; } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement) - */ @Override public int visit(IASTStatement statement) { if (statement instanceof IASTProblemHolder) @@ -207,9 +198,6 @@ public class CVisitor extends ASTQueries { return PROCESS_CONTINUE; } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId) - */ @Override public int visit(IASTTypeId typeId) { if (typeId instanceof IASTProblemHolder) @@ -266,9 +254,6 @@ public class CVisitor extends ASTQueries { this.binding = binding; } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator) - */ @Override public int visit(IASTDeclarator declarator) { //GCC allows declarations in expressions, so we have to continue from the @@ -309,9 +294,6 @@ public class CVisitor extends ASTQueries { return PROCESS_CONTINUE; } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDeclSpecifier(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier) - */ @Override public int visit(IASTDeclSpecifier declSpec) { if (compositeTypeDeclared && declSpec instanceof ICASTTypedefNameSpecifier) @@ -348,9 +330,6 @@ public class CVisitor extends ASTQueries { return PROCESS_CONTINUE; } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processEnumerator(org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator) - */ @Override public int visit(IASTEnumerator enumerator) { if (binding instanceof IEnumerator && enumerator.getName().resolveBinding() == binding) { @@ -360,9 +339,6 @@ public class CVisitor extends ASTQueries { return PROCESS_CONTINUE; } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement) - */ @Override public int visit(IASTStatement statement) { if (statement instanceof IASTLabelStatement && binding instanceof ILabel) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index 88e1f9afc7a..bd63a89dfab 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2015 IBM Corporation and others. + * Copyright (c) 2005, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.eclipse.cdt.core.dom.ast.ASTCompletionNode; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTAlignmentSpecifier; @@ -1161,8 +1162,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { throwBacktrack(LA(1)); attributes = CollectionUtils.merge(attributes, __attribute_decl_seq(true, false)); break; - case IGCCToken.t__declspec: // __declspec precedes the identifier - if (identifier != null || !supportDeclspecSpecifiers) + case IGCCToken.t__declspec: + if (!supportDeclspecSpecifiers) throwBacktrack(LA(1)); __attribute_decl_seq(false, true); break; @@ -1748,7 +1749,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { consume(); n = getNodeFactory().newName(t.getCharImage()); setRange(n, t.getOffset(), t.getEndOffset()); - createCompletionNode(t).addName(n); + ASTCompletionNode node = createCompletionNode(t); + if (node != null) + node.addName(n); return n; default: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java index 6119aebacb2..e77cad25114 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java @@ -54,7 +54,7 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat // The following fields are used by the PDOM bindings and need to be volatile. private volatile ICPPBase[] fBases; private volatile ICPPMethod[] ownInheritedConstructors; - private final ThreadLocal<Boolean> fComputingBases = new ThreadLocal<Boolean>() { + private final ThreadLocal<Boolean> fComputingBases = new ThreadLocal<>() { @Override protected Boolean initialValue() { return false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java index 1c67f88bdb4..f87b38da7b9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java @@ -16,6 +16,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.Optional; + import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTExpression; @@ -27,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecCompoundStatement; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecFor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecSimpleDeclaration; @@ -252,7 +255,8 @@ public class CPPASTForStatement extends CPPASTAttributeOwner implements ICPPASTF : null; ICPPASTExpression iterationExpr = (ICPPASTExpression) getIterationExpression(); ICPPEvaluation iterationEval = iterationExpr != null ? iterationExpr.getEvaluation() : null; - ICPPExecution bodyExec = EvalUtil.getExecutionFromStatement(getBody()); + ICPPExecution bodyExec = Optional.ofNullable(getBody()).map(EvalUtil::getExecutionFromStatement) + .orElseGet(() -> new ExecCompoundStatement()); return new ExecFor(initializerExec, conditionExprEval, conditionDeclExec, iterationEval, bodyExec); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java index c5a448159c7..c5635490efd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java @@ -54,6 +54,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS private boolean isConst; private boolean isMutable; private RefQualifier refQualifier; + private boolean isConstexpr; private ICPPFunctionScope scope; @@ -78,6 +79,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS copy.isConst = isConst; copy.isMutable = isMutable; copy.refQualifier = refQualifier; + copy.isConstexpr = isConstexpr; for (IASTParameterDeclaration param : getParameters()) { copy.addParameterDeclaration(param == null ? null : param.copy(style)); @@ -404,4 +406,15 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS } return null; } + + @Override + public boolean isConstexpr() { + return isConstexpr; + } + + @Override + public void setConstexpr(boolean value) { + assertNotFrozen(); + this.isConstexpr = value; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java index c26dde91be6..d51a95775a9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java @@ -17,6 +17,9 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter.EMPTY_CPPPARAMETER_ARRAY; +import java.text.MessageFormat; + +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; @@ -58,10 +61,16 @@ public class CPPBasicType implements ICPPBasicType, ISerializableType { public static final CPPBasicType CHAR = new CPPBasicType(Kind.eChar, 0); public static final CPPBasicType VOID = new CPPBasicType(Kind.eVoid, 0); - private static final int FROM_STRING_LITERAL = 1 << 31; + public static final int FROM_LITERAL = 1 << 30; + public static final int FROM_STRING_LITERAL = 1 << 31; + + private static final short TYPE_BUFFER_KIND_OFFSET = ITypeMarshalBuffer.FIRST_FLAG; + private static final short TYPE_BUFFER_FROM_LITERAL_FLAG = ITypeMarshalBuffer.SECOND_LAST_FLAG / 2; + private static final short TYPE_BUFFER_FIRST_FLAG_AFTER_KIND = TYPE_BUFFER_FROM_LITERAL_FLAG; + private static final int MAX_KIND_INT_VALUE = (TYPE_BUFFER_FIRST_FLAG_AFTER_KIND - 1) / TYPE_BUFFER_KIND_OFFSET; private final Kind fKind; - private final int fModifiers; + private int fModifiers; private Long fAssociatedValue; private ICPPFunction fPseudoDestructor; @@ -77,9 +86,11 @@ public class CPPBasicType implements ICPPBasicType, ISerializableType { } else { fKind = kind; } - if (expression instanceof IASTLiteralExpression - && ((IASTLiteralExpression) expression).getKind() == IASTLiteralExpression.lk_string_literal) { - qualifiers |= FROM_STRING_LITERAL; + if (expression instanceof IASTLiteralExpression) { + qualifiers |= FROM_LITERAL; + if (((IASTLiteralExpression) expression).getKind() == IASTLiteralExpression.lk_string_literal) { + qualifiers |= FROM_STRING_LITERAL; + } } fModifiers = qualifiers; if (expression instanceof ICPPASTInitializerClause) { @@ -209,9 +220,19 @@ public class CPPBasicType implements ICPPBasicType, ISerializableType { @Override public CPPBasicType clone() { + return clone(~0); + } + + /** + * Clone as normal but keep only requested flags. + * + * @param flagsMask The mask of flags to preserve during the clone. + */ + public CPPBasicType clone(int flagsMask) { CPPBasicType t = null; try { t = (CPPBasicType) super.clone(); + t.fModifiers &= flagsMask; } catch (CloneNotSupportedException e) { // Not going to happen. } @@ -235,15 +256,22 @@ public class CPPBasicType implements ICPPBasicType, ISerializableType { } /** - * Returns {@code true} if the type was created for a string literal. + * Returns {@code true} if the type was created from a string literal. */ public final boolean isFromStringLiteral() { return (fModifiers & FROM_STRING_LITERAL) != 0; } + /** + * Returns {@code true} if the type was created from a literal. + */ + public final boolean isFromLiteral() { + return (fModifiers & FROM_LITERAL) != 0; + } + @Override public final int getModifiers() { - return fModifiers & ~FROM_STRING_LITERAL; + return fModifiers & ~FROM_STRING_LITERAL & ~FROM_LITERAL; } @Override @@ -254,27 +282,47 @@ public class CPPBasicType implements ICPPBasicType, ISerializableType { @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { final int kind = getKind().ordinal(); - final int shiftedKind = kind * ITypeMarshalBuffer.FIRST_FLAG; + // 'kind' uses the space of the first few flags so make sure it doesn't overflow to the actual used flags further. + if (kind > MAX_KIND_INT_VALUE) { + throw new CoreException(CCorePlugin.createStatus( + MessageFormat.format("Cannot marshal a basic type, kind ''{0}'' would overflow following flags.", //$NON-NLS-1$ + getKind().toString()))); + } + final int shiftedKind = kind * TYPE_BUFFER_KIND_OFFSET; final int modifiers = getModifiers(); short firstBytes = (short) (ITypeMarshalBuffer.BASIC_TYPE | shiftedKind); - if (modifiers != 0) - firstBytes |= ITypeMarshalBuffer.LAST_FLAG; + if (isFromLiteral()) + firstBytes = setFirstBytesFlag(firstBytes, TYPE_BUFFER_FROM_LITERAL_FLAG); if (fAssociatedValue != null) - firstBytes |= ITypeMarshalBuffer.SECOND_LAST_FLAG; + firstBytes = setFirstBytesFlag(firstBytes, ITypeMarshalBuffer.SECOND_LAST_FLAG); + if (modifiers != 0) + firstBytes = setFirstBytesFlag(firstBytes, ITypeMarshalBuffer.LAST_FLAG); buffer.putShort(firstBytes); if (modifiers != 0) buffer.putByte((byte) modifiers); if (fAssociatedValue != null) buffer.putLong(getAssociatedNumericalValue()); + + } + + private static short setFirstBytesFlag(short firstBytes, short flag) throws CoreException { + if (flag < TYPE_BUFFER_FIRST_FLAG_AFTER_KIND) { + throw new CoreException(CCorePlugin.createStatus( + MessageFormat.format("Cannot marshal a basic type, flag ''0x{0}'' overlaps ''kind'' bytes.", //$NON-NLS-1$ + Integer.toHexString(flag)))); + } + return (short) (firstBytes | flag); } public static IType unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException { final boolean haveModifiers = (firstBytes & ITypeMarshalBuffer.LAST_FLAG) != 0; final boolean haveAssociatedNumericalValue = (firstBytes & ITypeMarshalBuffer.SECOND_LAST_FLAG) != 0; int modifiers = 0; - int kind = (firstBytes & (ITypeMarshalBuffer.SECOND_LAST_FLAG - 1)) / ITypeMarshalBuffer.FIRST_FLAG; + int kind = (firstBytes & (TYPE_BUFFER_FIRST_FLAG_AFTER_KIND - 1)) / TYPE_BUFFER_KIND_OFFSET; if (haveModifiers) modifiers = buffer.getByte(); + if ((firstBytes & TYPE_BUFFER_FROM_LITERAL_FLAG) != 0) + modifiers |= FROM_LITERAL; CPPBasicType result = new CPPBasicType(Kind.values()[kind], modifiers); if (haveAssociatedNumericalValue) result.setAssociatedNumericalValue(buffer.getLong()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java index 3dd21dc3de9..754da65a108 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java @@ -38,9 +38,16 @@ public class CPPBuiltinParameter extends PlatformObject implements ICPPParameter } private IType type; + private int position; public CPPBuiltinParameter(IType type) { this.type = type; + this.position = -1; + } + + public CPPBuiltinParameter(IType type, int position) { + this.type = type; + this.position = position; } @Override @@ -75,6 +82,9 @@ public class CPPBuiltinParameter extends PlatformObject implements ICPPParameter @Override public String getName() { + if (position != -1) { + return "arg" + position; //$NON-NLS-1$ + } return ""; //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java index 174e0e260f8..64271bedd79 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java @@ -46,6 +46,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; +import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.IRecursionResolvingBinding; @@ -161,6 +162,11 @@ public class CPPClassSpecialization extends CPPSpecialization public boolean isConstexpr() { return false; } + + @Override + public boolean isNoDiscard() { + return false; + } } public final static class RecursionResolvingConstructor extends RecursionResolvingMethod @@ -184,7 +190,7 @@ public class CPPClassSpecialization extends CPPSpecialization private ICPPClassSpecializationScope specScope; private ObjectMap specializationMap = ObjectMap.EMPTY_MAP; private ICPPBase[] bases; - private final ThreadLocal<Set<IBinding>> fInProgress = new ThreadLocal<Set<IBinding>>() { + private final ThreadLocal<Set<IBinding>> fInProgress = new ThreadLocal<>() { @Override protected Set<IBinding> initialValue() { return new HashSet<>(); @@ -502,6 +508,23 @@ public class CPPClassSpecialization extends CPPSpecialization if (typeSpecifier != null) { return typeSpecifier.isFinal(); } + ICPPClassType clazz = getSpecializedBinding(); + if (clazz != null) { + return clazz.isFinal(); + } + return false; + } + + @Override + public boolean isNoDiscard() { + ICPPASTCompositeTypeSpecifier typeSpecifier = getCompositeTypeSpecifier(); + if (typeSpecifier != null) { + return AttributeUtil.hasNodiscardAttribute(typeSpecifier); + } + ICPPClassType clazz = getSpecializedBinding(); + if (clazz != null) { + return clazz.isNoDiscard(); + } return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java index f83a4e1092d..2a236677acb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -44,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; /** @@ -267,6 +268,15 @@ public class CPPClassTemplate extends CPPTemplateDefinition } @Override + public boolean isNoDiscard() { + ICPPASTCompositeTypeSpecifier typeSpecifier = getCompositeTypeSpecifier(); + if (typeSpecifier != null) { + return AttributeUtil.hasNodiscardAttribute(typeSpecifier); + } + return false; + } + + @Override public int getVisibility(IBinding member) { return ClassTypeHelper.getVisibility(this, member); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java index 681b04811ef..b6dcea7c474 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java @@ -44,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; @@ -142,6 +143,11 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp public int getVisibility(IBinding member) { throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$ } + + @Override + public boolean isNoDiscard() { + return false; + } } private IASTName definition; @@ -455,6 +461,15 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp return false; } + @Override + public boolean isNoDiscard() { + ICPPASTCompositeTypeSpecifier typeSpecifier = getCompositeTypeSpecifier(); + if (typeSpecifier != null) { + return AttributeUtil.hasNodiscardAttribute(typeSpecifier); + } + return false; + } + private IASTName stripQualifier(IASTName name) { if (name instanceof ICPPASTQualifiedName) { name = ((ICPPASTQualifiedName) name).getLastName(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java index db6b297c23c..e48cdcc4b2b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java @@ -103,7 +103,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP // Deleted copy assignment operator: A& operator = (const A &) IType refType = new CPPReferenceType(this, false); ICPPFunctionType ft = CPPVisitor.createImplicitFunctionType(refType, ps, false, false); - ICPPMethod m = new CPPImplicitMethod(scope, OverloadableOperator.ASSIGN.toCharArray(), ft, ps, false); + CPPImplicitMethod m = new CPPImplicitMethod(scope, OverloadableOperator.ASSIGN.toCharArray(), ft, ps, false); result[2] = m; // Destructor: ~A() @@ -120,22 +120,28 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP ICPPParameter[] params = getParameters(); char[] operatorParensName = OverloadableOperator.PAREN.toCharArray(); + ICPPASTFunctionDeclarator dtor = fLambdaExpression.getDeclarator(); + boolean constExpr = false; + if (dtor != null) { + constExpr = dtor.isConstexpr(); + } if (isGeneric()) { m = new CPPImplicitMethodTemplate(getInventedTemplateParameterList(), scope, operatorParensName, ft, params, - false) { + constExpr) { @Override public boolean isImplicit() { return false; } }; } else { - m = new CPPImplicitMethod(scope, operatorParensName, ft, params, false) { + m = new CPPImplicitMethod(scope, operatorParensName, ft, params, constExpr) { @Override public boolean isImplicit() { return false; } }; } + m.addDefinition(fLambdaExpression.getDeclarator()); result[4] = m; // Conversion operator @@ -156,14 +162,14 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP templateParamClones[i] = (ICPPTemplateParameter) ((IType) templateParams[i]).clone(); } m = new CPPImplicitMethodTemplate(templateParamClones, scope, conversionOperatorName, ft, params, - false) { + constExpr) { @Override public boolean isImplicit() { return false; } }; } else { - m = new CPPImplicitMethod(scope, conversionOperatorName, ft, params, false) { + m = new CPPImplicitMethod(scope, conversionOperatorName, ft, params, constExpr) { @Override public boolean isImplicit() { return false; @@ -586,4 +592,9 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP return CPPClosureType.this.getConstructors(); } } + + @Override + public boolean isNoDiscard() { + return false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java index b95497e699e..d648d17d3e2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java @@ -179,6 +179,11 @@ public class CPPDeferredClassInstance extends CPPUnknownBinding } @Override + public boolean isNoDiscard() { + return false; + } + + @Override public ICPPTemplateArgument[] getTemplateArguments() { return fArguments; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java index cf64816dfbc..9d6d8b2afd2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java @@ -160,6 +160,11 @@ public class CPPDeferredFunction extends CPPUnknownBinding } @Override + public boolean isNoDiscard() { + return false; + } + + @Override public int getRequiredArgumentCount() { return 0; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java index 82db1bb7345..abb80fb5044 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java @@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; @@ -90,6 +91,11 @@ public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, I public ICPPScope asScope() { return this; } + + @Override + public boolean isNoDiscard() { + return false; + } } private final boolean fIsScoped; @@ -339,4 +345,18 @@ public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, I node.accept(action); } } + + @Override + public boolean isNoDiscard() { + findDefinition(); + IASTName def = getDefinition(); + if (def == null) { + ICPPEnumeration indexBinding = getIndexBinding(); + if (indexBinding != null) { + return indexBinding.isNoDiscard(); + } + def = getADeclaration(); + } + return AttributeUtil.hasNodiscardAttribute(((ICPPASTEnumerationSpecifier) def.getParent())); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java index 4bb3faa93ec..5f0d7d90746 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java @@ -162,4 +162,9 @@ public class CPPEnumerationSpecialization extends CPPSpecialization implements I } return enumerator; } + + @Override + public boolean isNoDiscard() { + return getSpecializedBinding().isNoDiscard(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index e1ba75cbf15..89972bb48ce 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -41,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; @@ -103,6 +104,11 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt public int getRequiredArgumentCount() { return 0; } + + @Override + public boolean isNoDiscard() { + return false; + } } public static final ICPPFunction UNINITIALIZED_FUNCTION = new CPPFunction(null) { @@ -625,8 +631,9 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt @Override public boolean isConstexpr() { ICPPASTDeclSpecifier declSpec = getDeclSpecifier(); - if (declSpec == null) + if (declSpec == null) { return false; + } return declSpec.isConstexpr(); } @@ -737,6 +744,11 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt return isNoReturn(getPreferredDtor()); } + @Override + public boolean isNoDiscard() { + return isNoDiscard(getPreferredDtor()); + } + public static boolean isNoReturn(ICPPASTFunctionDeclarator dtor) { if (dtor == null) { return false; @@ -751,6 +763,20 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt return false; } + public static boolean isNoDiscard(ICPPASTFunctionDeclarator dtor) { + if (dtor == null) { + return false; + } + if (AttributeUtil.hasNodiscardAttribute(dtor)) { + return true; + } + IASTNode parent = dtor.getParent(); + if (parent instanceof IASTAttributeOwner) { + return AttributeUtil.hasNodiscardAttribute((IASTAttributeOwner) parent); + } + return false; + } + public static ICPPExecution getFunctionBodyExecution(ICPPFunction function) { if (function instanceof ICPPComputableFunction) { return ((ICPPComputableFunction) function).getFunctionBodyExecution(); @@ -775,8 +801,22 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt } public static ICPPExecution computeFunctionBodyExecution(IASTNode def) { - ICPPASTFunctionDefinition fnDef = getFunctionDefinition(def); - if (fnDef != null) { + + while (def != null && !(def instanceof IASTDeclaration) && !(def instanceof ICPPASTLambdaExpression)) { + def = def.getParent(); + } + if (def == null) + return null; + + if (def instanceof ICPPASTLambdaExpression) { + ICPPASTLambdaExpression lambda = (ICPPASTLambdaExpression) def; + ((ASTNode) lambda).resolvePendingAmbiguities(); + if (lambda.getBody() instanceof CPPASTCompoundStatement) { + CPPASTCompoundStatement body = (CPPASTCompoundStatement) lambda.getBody(); + return body.getExecution(); + } + } else if (def instanceof ICPPASTFunctionDefinition) { + ICPPASTFunctionDefinition fnDef = (ICPPASTFunctionDefinition) def; // Make sure ambiguity resolution has been performed on the function body, even // if it's a class method and we're still processing the class declaration. ((ASTNode) fnDef).resolvePendingAmbiguities(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java index e6c2feb213b..c934385971a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java @@ -64,9 +64,6 @@ public class CPPFunctionInstance extends CPPFunctionSpecialization implements IC return false; } - /* (non-Javadoc) - * For debug purposes only - */ @Override public String toString() { return getName() + " " + ASTTypeUtil.getArgumentListString(fArguments, true); //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java index bba88ff46df..65aaaf44918 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java @@ -341,4 +341,12 @@ public class CPPFunctionSpecialization extends CPPSpecialization } return CPPTemplates.instantiateFunctionBody(this); } + + @Override + public boolean isNoDiscard() { + ICPPFunction f = (ICPPFunction) getSpecializedBinding(); + if (f != null) + return f.isNoDiscard(); + return false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java index a5e631763ee..82dc9160332 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java @@ -392,6 +392,11 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu return CPPFunction.isNoReturn(getFirstFunctionDtor()); } + @Override + public boolean isNoDiscard() { + return CPPFunction.isNoDiscard(getFirstFunctionDtor()); + } + private IASTDeclarator getDeclaratorByName(IASTNode node) { // Skip qualified names and nested declarators. while (node != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java index 6a2eb7e0e7a..2186b88c1c9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java @@ -15,12 +15,14 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.CoreException; public class CPPQualifierType implements IQualifierType, ITypeContainer, ISerializableType { @@ -38,8 +40,18 @@ public class CPPQualifierType implements IQualifierType, ITypeContainer, ISerial public boolean isSameType(IType o) { if (o instanceof ITypedef) return o.isSameType(this); - if (!(o instanceof IQualifierType)) + if (!(o instanceof IQualifierType)) { + // Handle the case where we store the qualifiers in the IPointerType. + if (o instanceof IPointerType) { + IType nested = SemanticUtil.getSimplifiedType(type); + if (nested instanceof IPointerType) { + IPointerType pt = (IPointerType) o; + return isConst() == pt.isConst() && isVolatile() == pt.isVolatile() + && ((IPointerType) nested).getType().isSameType(pt.getType()); + } + } return false; + } IQualifierType pt = (IQualifierType) o; if (isConst() == pt.isConst() && isVolatile() == pt.isVolatile() && type != null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java index c26466b0f54..f611b368510 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java @@ -260,6 +260,11 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter } @Override + public boolean isNoDiscard() { + return false; + } + + @Override public int getVisibility(IBinding member) { throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java index 2450a2a8957..b87ec89745d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java @@ -128,6 +128,11 @@ public class CPPTemplateTemplateParameterSpecialization extends CPPTemplateParam } @Override + public boolean isNoDiscard() { + return false; + } + + @Override public int getVisibility(IBinding member) { return getSpecializedBinding().getVisibility(member); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMemberClass.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMemberClass.java index c347d7cf817..db1b181bf19 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMemberClass.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMemberClass.java @@ -140,6 +140,11 @@ public class CPPUnknownMemberClass extends CPPUnknownMember implements ICPPUnkno } @Override + public boolean isNoDiscard() { + return false; + } + + @Override public int getVisibility(IBinding member) { throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMethod.java index abe90b7f058..c4a169a53fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMethod.java @@ -174,4 +174,9 @@ public class CPPUnknownMethod extends CPPUnknownMember implements ICPPMethod { public boolean isConstexpr() { return false; } + + @Override + public boolean isNoDiscard() { + return false; + } } 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 b77e1b87038..78099e91259 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 @@ -69,7 +69,7 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV * The set of CPPVariable objects for which initial value computation is in progress on each thread. * This is used to guard against recursion during initial value computation. */ - private static final ThreadLocal<Set<CPPVariable>> fInitialValueInProgress = new ThreadLocal<Set<CPPVariable>>() { + private static final ThreadLocal<Set<CPPVariable>> fInitialValueInProgress = new ThreadLocal<>() { @Override protected Set<CPPVariable> initialValue() { return new HashSet<>(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index ebdf710df1d..4709d51a4e7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2002, 2016 IBM Corporation and others. + * Copyright (c) 2002, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -462,7 +462,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { switch (nt.getType()) { case IToken.tEOC: case IToken.tCOMPLETION: - createCompletionNode(nt).addName(name); + ASTCompletionNode node = createCompletionNode(nt); + if (node != null) + node.addName(name); break; } return name; @@ -1538,7 +1540,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IGCCToken.t___alignof__: return parseTypeidInParenthesisOrUnaryExpression(false, consume().getOffset(), IASTTypeIdExpression.op_alignof, IASTUnaryExpression.op_alignOf, ctx, strat); - + case IGCCToken.tTT_integer_pack: + return unaryExpression(IASTUnaryExpression.op_integerPack, ctx, strat); case IGCCToken.tTT_has_nothrow_assign: case IGCCToken.tTT_has_nothrow_constructor: case IGCCToken.tTT_has_nothrow_copy: @@ -1563,6 +1566,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IGCCToken.tTT_is_trivially_constructible: case IGCCToken.tTT_is_trivially_assignable: case IGCCToken.tTT_is_constructible: + case IGCCToken.tTT_is_same: return parseTypeTrait(); default: @@ -1614,6 +1618,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { switch (first.getType()) { case IGCCToken.tTT_is_base_of: case IGCCToken.tTT_is_trivially_assignable: + case IGCCToken.tTT_is_same: return true; } return false; @@ -1634,6 +1639,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return IASTBinaryTypeIdExpression.Operator.__is_base_of; case IGCCToken.tTT_is_trivially_assignable: return IASTBinaryTypeIdExpression.Operator.__is_trivially_assignable; + case IGCCToken.tTT_is_same: + return IASTBinaryTypeIdExpression.Operator.__is_same; } assert false; @@ -3572,8 +3579,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { throwBacktrack(LA(1)); attributes = CollectionUtils.merge(attributes, __attribute_decl_seq(true, false)); break; - case IGCCToken.t__declspec: // __declspec precedes the identifier - if (identifier != null || !supportDeclspecSpecifiers) + case IGCCToken.t__declspec: + if (!supportDeclspecSpecifiers) throwBacktrack(LA(1)); attributes = CollectionUtils.merge(attributes, __attribute_decl_seq(false, true)); break; @@ -4796,9 +4803,19 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { // cv-qualifiers if (isLambdaDeclarator) { - if (LT(1) == IToken.t_mutable) { - fc.setMutable(true); - endOffset = consume().getEndOffset(); + specloop: while (true) { + switch (LT(1)) { + case IToken.t_mutable: + fc.setMutable(true); + endOffset = consume().getEndOffset(); + break; + case IToken.t_constexpr: + fc.setConstexpr(true); + endOffset = consume().getEndOffset(); + break; + default: + break specloop; + } } } else { cvloop: while (true) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java index 61b889c2838..fb9063fb7d3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization; */ public final class InstantiationContext { private CPPTemplateParameterMap parameterMap; + private boolean forDeduction = false; private int packOffset; private final ICPPSpecialization contextSpecialization; private boolean expandPack; @@ -79,6 +80,15 @@ public final class InstantiationContext { } /** + * Create an InstantiationContext for a template parameter map, for use template argument deduction. + */ + public static InstantiationContext forDeduction(ICPPTemplateParameterMap parameterMap) { + InstantiationContext result = new InstantiationContext(parameterMap); + result.forDeduction = true; + return result; + } + + /** * Returns the mapping of template parameters to arguments, possibly {@code null} if the context doesn't * contain it. */ @@ -87,6 +97,13 @@ public final class InstantiationContext { } /** + * Returns whether the InstantiationContext was created during template argument deduction. + */ + public boolean isForDeduction() { + return forDeduction; + } + + /** * Adds a parameter mapping. */ public void addToParameterMap(ICPPTemplateParameter par, ICPPTemplateArgument arg) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java index 71790051d2e..49798f6f32c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java @@ -14,6 +14,7 @@ import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; @@ -131,6 +132,15 @@ class AggregateInitialization { */ private Cost checkInitializationOfElements(IType type, Cost worstCost) throws DOMException { if (type instanceof ICPPClassType && isAggregate(type)) { + ICPPBase[] bases = ((ICPPClassType) type).getBases(); + for (ICPPBase base : bases) { + Cost cost = checkElement(base.getBaseClassType(), null, worstCost); + if (!cost.converts()) + return cost; + if (cost.compareTo(worstCost) > 0) { + worstCost = cost; + } + } ICPPField[] fields = getFieldsForAggregateInitialization((ICPPClassType) type); for (ICPPField field : fields) { Cost cost = checkElement(field.getType(), field.getInitialValue(), worstCost); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AutoTypeResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AutoTypeResolver.java index 8a4bb012a8c..4f2c88e64fa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AutoTypeResolver.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AutoTypeResolver.java @@ -183,4 +183,9 @@ class AutoTypeResolver implements ICPPFunctionTemplate { public boolean isNoReturn() { throw new UnsupportedOperationException(UNEXPECTED_CALL); } + + @Override + public boolean isNoDiscard() { + throw new UnsupportedOperationException(UNEXPECTED_CALL); + } }
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java index 0c790cd01f0..ee6b4bd1546 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java @@ -76,10 +76,9 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding { } @Override - @SuppressWarnings("unchecked") - public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + public <T> T getAdapter(Class<T> adapter) { if (adapter.isAssignableFrom(getClass())) - return this; + return adapter.cast(this); return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index bcb87fc8d92..45f8fb677b5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -231,6 +231,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownField; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMemberClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMethod; @@ -298,14 +299,14 @@ public class CPPSemantics { // that are not reachable via includes from the file containing the name. // Generally this is not allowed, but certain consumers, such as IncludeOrganizer, // need it (since the whole point of IncludeOrganizer is to find missing headers). - private static final ThreadLocal<Boolean> fAllowPromiscuousBindingResolution = new ThreadLocal<Boolean>() { + private static final ThreadLocal<Boolean> fAllowPromiscuousBindingResolution = new ThreadLocal<>() { @Override protected Boolean initialValue() { return false; } }; - private static final ThreadLocal<Deque<IASTNode>> fLookupPoints = new ThreadLocal<Deque<IASTNode>>() { + private static final ThreadLocal<Deque<IASTNode>> fLookupPoints = new ThreadLocal<>() { @Override protected Deque<IASTNode> initialValue() { return new ArrayDeque<>(); @@ -1142,7 +1143,7 @@ public class CPPSemantics { return; } - if (data.qualified && !(scope instanceof ICPPTemplateScope)) { + if (!data.isDestructor && data.qualified && !(scope instanceof ICPPTemplateScope)) { if (data.ignoreUsingDirectives || data.usingDirectives.isEmpty()) return; data.usingDirectivesOnly = true; @@ -1249,6 +1250,7 @@ public class CPPSemantics { ld2.fHeuristicBaseLookup = data.fHeuristicBaseLookup; ld2.qualified = parent instanceof ICPPASTQualifiedName; ld2.typesOnly = true; + ld2.isDestructor = true; lookup(ld2, getLookupScope(typeDtorName)); IBinding[] typedefs = ld2.getFoundBindings(); ITypedef typedef = null; @@ -2653,7 +2655,7 @@ public class CPPSemantics { } } } - return result; + return ArrayUtil.trim(result); } /** @@ -3453,11 +3455,10 @@ public class CPPSemantics { data.setFunctionArguments(false, createArgForType(exp, charArray)); ret = resolveFunction(data, funcs, true, false); - // char[] stringLiteral = exp.getValue(); // The string literal that was passed to the operator // The string literal is passed to the operator as chars: - // "literal"_op -> operator "" _op<'l', 'i', 't', 'e', 'r', 'a', 'l'>(); + // 12345_op -> operator "" _op<'1', '2', '3', '4', '5'>(); ICPPTemplateArgument args[] = new ICPPTemplateArgument[stringLiteral.length]; for (int k = 0; k < stringLiteral.length; k++) { args[k] = new CPPTemplateNonTypeArgument( @@ -3492,13 +3493,48 @@ public class CPPSemantics { * str (i.e., its length excluding the terminating null character). * L is treated as operator "" X(str, len) */ - CPPPointerType strType = new CPPPointerType( - new CPPBasicType(((CPPASTLiteralExpression) exp).getBasicCharKind(), 0, null), true, false, - false); + IType charType = new CPPBasicType(((CPPASTLiteralExpression) exp).getBasicCharKind(), 0, null); + CPPPointerType strType = new CPPPointerType(charType, true, false, false); IASTInitializerClause[] initializer = new IASTInitializerClause[] { createArgForType(exp, strType), createArgForType(null, CPPBasicType.UNSIGNED_INT) }; data.setFunctionArguments(false, initializer); ret = resolveFunction(data, funcs, true, false); + + // GNU extension: allow literal operator templates for string literals. + // The implementation follows the proposed spec in + // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3599.html. + char[] stringLiteral = exp.getValue(); // The string literal that was passed to the operator + + // The operator template is expected to take the character type as its first argument, + // followed by the characters as non-type arguments. + // "literal"_op -> operator "" _op<char, 'l', 'i', 't', 'e', 'r', 'a', 'l'>(); + ICPPTemplateArgument args[] = new ICPPTemplateArgument[stringLiteral.length + 1]; + args[0] = new CPPTemplateTypeArgument(charType); + for (int k = 0; k < stringLiteral.length; k++) { + args[k + 1] = new CPPTemplateNonTypeArgument( + new EvalFixed(CPPBasicType.CHAR, PRVALUE, IntegralValue.create(stringLiteral[k]))); + } + + data = new LookupData(((CPPASTLiteralExpression) exp).getOperatorName(), args, exp); + IBinding litTpl = resolveFunction(data, tplFunctions, true, false); + + // Do we have valid template and non-template bindings? + if (ret != null && !(ret instanceof IProblemBinding)) { + // Do we have valid template and non-template bindings? + if (litTpl instanceof ICPPFunctionInstance) { + // Ambiguity? It has two valid options, and the spec says it shouldn't + return new ProblemBinding(data.getLookupName(), exp, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, + tplFunctions); + } + } else { + if (litTpl instanceof ICPPFunctionInstance) { + // Only the template binding is valid + ret = litTpl; + } else { + // Couldn't find a valid operator + return ret; + } + } } else if (kind == IASTLiteralExpression.lk_char_constant) { /* * 2.14.8.6 @@ -3743,7 +3779,13 @@ public class CPPSemantics { if (CPPTemplates.isDependentType(sourceType)) { IType[] tmp = { sourceType }; setTargetedFunctionsToUnknown(tmp); - return CPPDeferredFunction.createForCandidates(type.getConstructors()); + ICPPConstructor[] ctors = type.getConstructors(); + if (ctors != null && ctors.length > 0) { + return CPPDeferredFunction.createForCandidates(ctors); + } else { + return new ProblemBinding(typeId, ISemanticProblem.BINDING_NOT_FOUND, + type.getNameCharArray()); + } } Cost c; if (calculateInheritanceDepth(sourceType, type) >= 0) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 07e27e0a235..ba0378e9f23 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -239,13 +239,13 @@ public class CPPTemplates { // Infrastructure to protect against rogue template metaprograms that don't terminate. private static final int TEMPLATE_INSTANTIATION_DEPTH_LIMIT = 128; - private static final ThreadLocal<Integer> fTemplateInstantiationDepth = new ThreadLocal<Integer>() { + private static final ThreadLocal<Integer> fTemplateInstantiationDepth = new ThreadLocal<>() { @Override protected Integer initialValue() { return 0; } }; - private static final ThreadLocal<Set<TypeInstantiationRequest>> instantiationsInProgress = new ThreadLocal<Set<TypeInstantiationRequest>>() { + private static final ThreadLocal<Set<TypeInstantiationRequest>> instantiationsInProgress = new ThreadLocal<>() { @Override protected Set<TypeInstantiationRequest> initialValue() { return new HashSet<>(); @@ -1717,12 +1717,7 @@ public class CPPTemplates { if (type instanceof ICPPUnaryTypeTransformation) { ICPPUnaryTypeTransformation typeTransformation = (ICPPUnaryTypeTransformation) type; IType operand = instantiateType(typeTransformation.getOperand(), context); - switch (typeTransformation.getOperator()) { - case underlying_type: - return TypeTraits.underlyingType(operand); - default: - return null; // shouldn't happen - } + return SemanticUtil.applyTypeTransformation(typeTransformation.getOperator(), operand); } if (type instanceof CPPClosureType) { @@ -2455,8 +2450,9 @@ public class CPPTemplates { result = new ICPPFunction[functions.length]; System.arraycopy(functions, 0, result, 0, i); } - result[i++] = inst; + result[i] = inst; } + i++; if (done) break; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java index e5ee18de9fa..d3029a98176 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java @@ -15,8 +15,11 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; +import java.util.Optional; + import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; @@ -25,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; @@ -36,8 +40,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTStructuredBindingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredFunction; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.VariableReadWriteFlags; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; @@ -50,7 +57,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; public final class CPPVariableReadWriteFlags extends VariableReadWriteFlags { private static CPPVariableReadWriteFlags INSTANCE = new CPPVariableReadWriteFlags(); - public static int getReadWriteFlags(IASTName variable) { + public static Optional<Integer> getReadWriteFlags(IASTName variable) { CPPSemantics.pushLookupPoint(variable); try { return INSTANCE.rwAnyNode(variable, 0); @@ -60,28 +67,29 @@ public final class CPPVariableReadWriteFlags extends VariableReadWriteFlags { } @Override - protected int rwAnyNode(IASTNode node, int indirection) { + protected Optional<Integer> rwAnyNode(IASTNode node, int indirection) { final IASTNode parent = node.getParent(); if (parent instanceof ICPPASTConstructorInitializer) { return rwInCtorInitializer(node, indirection, (ICPPASTConstructorInitializer) parent); } if (parent instanceof ICPPASTFieldDesignator) { - return WRITE; // Field is initialized via a designated initializer. + return Optional.of(WRITE); // Field is initialized via a designated initializer. } return super.rwAnyNode(node, indirection); } @Override - protected int rwInDeclarator(IASTDeclarator parent, int indirection) { + protected Optional<Integer> rwInDeclarator(IASTDeclarator parent, int indirection) { IType type = CPPVisitor.createType(parent); if (type instanceof ICPPUnknownType || type instanceof ICPPClassType && !TypeTraits.hasTrivialDefaultConstructor((ICPPClassType) type, CPPSemantics.MAX_INHERITANCE_DEPTH)) { - return WRITE; + return Optional.of(WRITE); } return super.rwInDeclarator(parent, indirection); } - private int rwInCtorInitializer(IASTNode node, int indirection, ICPPASTConstructorInitializer parent) { + private Optional<Integer> rwInCtorInitializer(IASTNode node, int indirection, + ICPPASTConstructorInitializer parent) { IASTNode grand = parent.getParent(); if (grand instanceof IASTDeclarator || grand instanceof ICPPASTNewExpression) { // Look for a constructor being called. @@ -112,33 +120,37 @@ public final class CPPVariableReadWriteFlags extends VariableReadWriteFlags { } else if (grand instanceof ICPPASTStructuredBindingDeclaration) { return rwInStructuredBinding((ICPPASTStructuredBindingDeclaration) grand); } - return READ | WRITE; // fallback + return Optional.empty(); // Fallback } @Override - protected int rwInUnaryExpression(IASTNode node, IASTUnaryExpression expr, int indirection) { + protected Optional<Integer> rwInUnaryExpression(IASTNode node, IASTUnaryExpression expr, int indirection) { switch (expr.getOperator()) { case ICPPASTUnaryExpression.op_typeid: - return 0; + return Optional.of(0); } return super.rwInUnaryExpression(node, expr, indirection); } @Override - protected int rwInFunctionName(IASTExpression node) { + protected Optional<Integer> rwInFunctionName(IASTExpression node) { if (!(node instanceof IASTIdExpression)) { IType type = node.getExpressionType(); if (type instanceof ICPPFunctionType && !((ICPPFunctionType) type).isConst()) - return READ | WRITE; + return Optional.of(READ | WRITE); } - return READ; + return Optional.of(READ); } @Override - protected int rwAssignmentToType(IType type, int indirection) { + protected Optional<Integer> rwAssignmentToType(IType type, int indirection) { + if (CPPTemplates.isDependentType(type)) { + return Optional.empty(); // Fallback + } + if (indirection == 0) { if (!(type instanceof ICPPReferenceType) || ((ICPPReferenceType) type).isRValueReference()) { - return READ; + return Optional.of(READ); } type = ((ICPPReferenceType) type).getType(); } @@ -150,11 +162,44 @@ public final class CPPVariableReadWriteFlags extends VariableReadWriteFlags { } if (indirection == 0) { if (type instanceof IQualifierType) { - return ((IQualifierType) type).isConst() ? READ : READ | WRITE; + return ((IQualifierType) type).isConst() ? Optional.of(READ) : Optional.of(READ | WRITE); } else if (type instanceof IPointerType) { - return ((IPointerType) type).isConst() ? READ : READ | WRITE; + return ((IPointerType) type).isConst() ? Optional.of(READ) : Optional.of(READ | WRITE); + } + } + return Optional.empty(); // Fallback + } + + @Override + protected Optional<Integer> rwArgumentForFunctionCall(final IASTFunctionCallExpression funcCall, IASTNode argument, + int indirection) { + // Handle deferred functions (unresolved overloads) by taking the union (bitwise or) + // of the flags of each candidate function. + IASTExpression functionNameExpression = funcCall.getFunctionNameExpression(); + if (functionNameExpression instanceof IASTIdExpression) { + IBinding b = ((IASTIdExpression) functionNameExpression).getName().resolveBinding(); + if (b instanceof ICPPDeferredFunction) { + ICPPDeferredFunction deferredFunc = (ICPPDeferredFunction) b; + ICPPFunction[] candidates = deferredFunc.getCandidates(); + if (candidates != null) { + IASTInitializerClause[] args = funcCall.getArguments(); + int argPos = ArrayUtil.indexOf(args, argument); + Optional<Integer> cumulative = Optional.empty(); + for (ICPPFunction f : candidates) { + if (f == null) { + continue; + } + IType type = f.getType(); + if (type instanceof IFunctionType) { + Optional<Integer> res = rwArgumentForFunctionCall((IFunctionType) type, argPos, + args[argPos], indirection); + cumulative = union(cumulative, res); + } + } + return cumulative; + } } } - return READ | WRITE; // fallback + return super.rwArgumentForFunctionCall(funcCall, argument, indirection); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 37f1353c852..6393d9cf453 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -236,7 +236,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownTypeScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariableTemplate; @@ -280,7 +279,7 @@ public class CPPVisitor extends ASTQueries { // Thread-local set of declarators for which auto types are being created. // Used to prevent infinite recursion while processing invalid self-referencing // auto-type declarations. - private static final ThreadLocal<Set<IASTDeclarator>> autoTypeDeclarators = new ThreadLocal<Set<IASTDeclarator>>() { + private static final ThreadLocal<Set<IASTDeclarator>> autoTypeDeclarators = new ThreadLocal<>() { @Override protected Set<IASTDeclarator> initialValue() { return new HashSet<>(); @@ -1733,7 +1732,7 @@ public class CPPVisitor extends ASTQueries { return areEquivalentBindings(candidate, target, index); } - private static boolean areEquivalentBindings(IBinding binding1, IBinding binding2, IIndex index) { + public static boolean areEquivalentBindings(IBinding binding1, IBinding binding2, IIndex index) { if (binding1.equals(binding2)) { return true; } @@ -2793,7 +2792,12 @@ public class CPPVisitor extends ASTQueries { name = ((IASTEnumerationSpecifier) declSpec).getName(); } else if (declSpec instanceof ICPPASTTypeTransformationSpecifier) { ICPPASTTypeTransformationSpecifier spec = (ICPPASTTypeTransformationSpecifier) declSpec; - return new CPPUnaryTypeTransformation(spec.getOperator(), createType(spec.getOperand())); + IType type = SemanticUtil.applyTypeTransformation(spec.getOperator(), createType(spec.getOperand())); + if (type != null) + return type; + + return ProblemType.UNRESOLVED_NAME; + } else if (declSpec instanceof ICPPASTSimpleDeclSpecifier) { ICPPASTSimpleDeclSpecifier spec = (ICPPASTSimpleDeclSpecifier) declSpec; // Check for decltype(expr) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index b4858bbd4b4..fb3d3e4157f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -30,6 +30,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.isVoidType; +import java.math.BigInteger; import java.util.Collections; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -60,6 +61,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; +import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; +import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; @@ -1168,9 +1171,13 @@ public class Conversions { if (basicType.getKind() == Kind.eNullPtr) return true; - Long val = basicType.getAssociatedNumericalValue(); - if (val != null && val == 0) { - return true; + // Starting from C++11, the value is required to be a literal. This means pre-C++11 parsing will not be correct here. + // But we don't currently have a way to check the C++ version here and in semantics code in general. + if (basicType.getKind() == Kind.eInt && basicType.isFromLiteral()) { + Long val = basicType.getAssociatedNumericalValue(); + if (val != null && val == 0) { + return true; + } } } return false; @@ -1322,4 +1329,99 @@ public class Conversions { private static boolean isNullPtr(IType t1) { return t1 instanceof IBasicType && ((IBasicType) t1).getKind() == Kind.eNullPtr; } + + /** + * Narrow a numeric value to the range of a specified type. + * @param num the value to narrow (may be null) + * @param toType the type to narrow to + * @return a number representing the narrowed value, or null + */ + public static Number narrowNumberValue(Number num, IType toType) { + if (num == null) + return null; + + if (toType instanceof IBasicType) { + IBasicType basicType = (IBasicType) toType; + IBasicType.Kind basicTypeKind = basicType.getKind(); + switch (basicTypeKind) { + case eFloat: + if (num instanceof Float) + return num; + return Float.valueOf(num.floatValue()); + case eDouble: + if (num instanceof Double) + return num; + return Double.valueOf(num.doubleValue()); + case eInt: + SizeAndAlignment sizeToType = SizeofCalculator.getSizeAndAlignment(toType); + if (sizeToType == null) + return null; + // Note in the following we don't check type.isSigned() since that checks for the + // explicit presence of the "signed" modifier. So instead check !type.isUnsigned(). + if (sizeToType.size <= 8) { + // First, mask the value to the correct size + // Note that we take the longValue here which may be negative even though the + // original value is positive; the masking here should still be correct and we + // should ultimately end up with the correct narrowed value, regardless. + long longVal = num.longValue(); + long maskVal = 0xFFFFFFFFFFFFFFFFL; + long signBit = 0x8000000000000000L; + // Calculate a mask to reduce the size of the value to the target width: + maskVal >>>= (8 - sizeToType.size) * 8; + signBit >>>= (8 - sizeToType.size) * 8; + if (!basicType.isUnsigned() && (longVal & signBit) != 0) { + // We need to extend the sign bit. + long signBits = ~maskVal; + longVal |= signBits; + } else { + longVal &= maskVal; + } + + // The Java type used to store the numerical value is independent of the associated + // C type, but we go with a smaller type (Integer) where possible. For 4 bytes + // (signed) or less than 4 bytes (signed or not) we can use Integer. For 8 bytes + // (signed) or less than 8 bytes (signed or not) we can use Long. Any larger and we + // resort to BigInteger. + if (longVal >= 0 && longVal <= Integer.MAX_VALUE) { + return Integer.valueOf((int) longVal); + } + if (!basicType.isUnsigned() && longVal >= Integer.MIN_VALUE && longVal <= Integer.MAX_VALUE) { + return Integer.valueOf((int) longVal); + } + + if (!basicType.isUnsigned() || longVal > 0) { + return Long.valueOf(longVal); + } + + BigInteger biVal = BigInteger.valueOf(longVal); + // 2**64 = 18446744073709551616 + biVal = biVal.add(new BigInteger("18446744073709551616")); //$NON-NLS-1$ + return biVal; + } + // TODO handle larger int sizes? + return null; + case eChar: + // TODO don't assume signed char + if (num instanceof Byte) + return num; + return Byte.valueOf(num.byteValue()); + case eChar16: + int intVal = num.intValue(); + int maskedVal = intVal & 0xFFFF; + if (maskedVal == intVal && num instanceof Integer) + return num; + return Integer.valueOf(maskedVal); + case eChar32: + long longVal = num.longValue(); + long maskedVal32 = longVal & 0xFFFFFFFFL; + if (maskedVal32 == longVal && (num instanceof Integer || num instanceof Long)) + return num; + return Long.valueOf(maskedVal32); + default: + return null; + } + } + + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java index 464e389ed49..8cfda662951 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java @@ -151,6 +151,11 @@ public class EvalBinary extends CPPDependentEvaluation { } } } + + if (fType instanceof CPPBasicType) { + fType = ((CPPBasicType) fType).clone(~CPPBasicType.FROM_LITERAL); + } + return fType; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java index 21aff0403ca..dc0d2369b94 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java @@ -80,6 +80,7 @@ public class EvalBinaryTypeId extends CPPDependentEvaluation { switch (fOperator) { case __is_base_of: case __is_trivially_assignable: + case __is_same: return CPPBasicType.BOOLEAN; } return ProblemType.UNKNOWN_FOR_EXPRESSION; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index 2da98771cf1..3ba549e475a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -112,7 +112,9 @@ public class EvalBinding extends CPPDependentEvaluation { if (fBinding == null) { // fParameterOwner is guaranteed to be not null. ICPPParameter[] parameters = fParameterOwner.getParameters(); - fBinding = parameters[fParameterPosition]; + if (parameters.length > fParameterPosition) { + fBinding = parameters[fParameterPosition]; + } } return fBinding; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java index bc49e2cd3d0..aa8c24ce186 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java @@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.DependentValue; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.IntegralValue; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext; import org.eclipse.core.runtime.CoreException; @@ -145,6 +146,9 @@ public class EvalComma extends CPPDependentEvaluation { public IType getType() { if (fType == null) { fType = computeType(); + if (fType instanceof CPPBasicType) { + fType = ((CPPBasicType) fType).clone(~CPPBasicType.FROM_LITERAL); + } } return fType; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java index 3af16b1d397..49cc3df4639 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java @@ -39,6 +39,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.IntegralValue; import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; @@ -180,6 +181,14 @@ public class EvalConditional extends CPPDependentEvaluation { if (fValueCategory != null) return; + evaluateInternal(); + + if (fType instanceof CPPBasicType) { + fType = ((CPPBasicType) fType).clone(~CPPBasicType.FROM_LITERAL); + } + } + + private void evaluateInternal() { fValueCategory = PRVALUE; final ICPPEvaluation positive = fPositive == null ? fCondition : fPositive; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index 47d757faf2f..5c30a9bd92e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -372,7 +372,7 @@ public final class EvalFunctionCall extends CPPDependentEvaluation { return EvalFixed.INCOMPLETE; } - private ICPPFunction resolveFunctionBinding() { + public ICPPFunction resolveFunctionBinding() { ICPPFunction function = getOverload(); if (function == null) { ICPPEvaluation funcEval = fArguments[0]; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java index 85bd7612c16..291a175a599 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java @@ -300,8 +300,17 @@ public class EvalTypeId extends CPPDependentEvaluation { ICPPClassType classType = (ICPPClassType) simplifiedType; ICPPEvaluation[] arguments = fArguments; ICPPConstructor[] constructors = classType.getConstructors(); - if (arguments.length == 1 && arguments[0] instanceof EvalInitList && !fUsesBracedInitList) { + if (fUsesBracedInitList && arguments.length > 0) { // List-initialization of a class (dcl.init.list-3). + // e.g. A{1,2} + ICPPConstructor[] ctors = getInitializerListConstructors(constructors); + if (ctors.length != 0) { + constructors = ctors; + arguments = new EvalInitList[] { new EvalInitList(arguments, getTemplateDefinition()) }; + } + } else if (arguments.length == 1 && arguments[0] instanceof EvalInitList && !fUsesBracedInitList) { + // List-initialization of a class (dcl.init.list-3). + // e.g. A({1,2}) if (TypeTraits.isAggregateClass(classType)) { // Pretend that aggregate initialization is calling the default constructor. return findDefaultConstructor(classType, constructors); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java index 1dde894ea42..79eb2395633 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java @@ -19,6 +19,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_alignOf; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_amper; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_bracketedPrimary; +import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_integerPack; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_minus; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_noexcept; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_not; @@ -156,6 +157,8 @@ public class EvalUnary extends CPPDependentEvaluation { return fArgument.referencesTemplateParameter(); case op_throw: return false; + case op_integerPack: + return true; default: return fArgument.isValueDependent(); } @@ -242,6 +245,8 @@ public class EvalUnary extends CPPDependentEvaluation { return CPPVisitor.get_type_info(); case op_throw: return CPPSemantics.VOID_TYPE; + case op_integerPack: + return fArgument.getType(); case op_amper: if (fAddressOfQualifiedNameBinding instanceof ICPPMember) { ICPPMember member = (ICPPMember) fAddressOfQualifiedNameBinding; @@ -394,6 +399,10 @@ public class EvalUnary extends CPPDependentEvaluation { @Override public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) { + if (fOperator == op_integerPack && context.getPackOffset() != -1) { + return new EvalFixed(getType(), ValueCategory.PRVALUE, IntegralValue.create(context.getPackOffset())); + } + ICPPEvaluation argument = fArgument.instantiate(context, maxDepth); IBinding binding = fAddressOfQualifiedNameBinding; if (binding instanceof ICPPUnknownBinding) { @@ -520,6 +529,15 @@ public class EvalUnary extends CPPDependentEvaluation { @Override public int determinePackSize(ICPPTemplateParameterMap tpMap) { + if (fOperator == op_integerPack) { + ICPPEvaluation instantiatedArg = fArgument.instantiate(new InstantiationContext(tpMap), + IntegralValue.MAX_RECURSION_DEPTH); + IValue value = instantiatedArg.getValue(); + if (value.numberValue() != null) { + return (int) value.numberValue().longValue(); + } + return CPPTemplates.PACK_SIZE_DEFER; + } return fArgument.determinePackSize(tpMap); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUtil.java index 3e668dce2ef..e41c71d1ca8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUtil.java @@ -39,7 +39,7 @@ public class EvalUtil { * The set of ICPPVariable objects for which initial value computation is in progress on each thread. * This is used to guard against recursion during initial value computation. */ - private static final ThreadLocal<Set<ICPPVariable>> fInitialValueInProgress = new ThreadLocal<Set<ICPPVariable>>() { + private static final ThreadLocal<Set<ICPPVariable>> fInitialValueInProgress = new ThreadLocal<>() { @Override protected Set<ICPPVariable> initialValue() { return new HashSet<>(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecBuiltin.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecBuiltin.java new file mode 100644 index 00000000000..86e6aab7ae2 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecBuiltin.java @@ -0,0 +1,195 @@ +/******************************************************************************* +* Copyright (c) 2022 Davin McCall and others. +* +* This program and the accompanying materials +* are made available under the terms of the Eclipse Public License 2.0 +* which accompanies this distribution, and is available at +* https://www.eclipse.org/legal/epl-2.0/ +* +* SPDX-License-Identifier: EPL-2.0 +* +* Contributors: +* Davin McCall - initial API and implementation +*******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; + +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; +import org.eclipse.cdt.internal.core.dom.parser.IntegralValue; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinParameter; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation.ConstexprEvaluationContext; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution; +import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext; +import org.eclipse.core.runtime.CoreException; + +/** + * Constexpr-evaluation for compiler builtin functions. + */ +public class ExecBuiltin implements ICPPExecution { + public final static short BUILTIN_FFS = 0, BUILTIN_FFSL = 1, BUILTIN_FFSLL = 2, BUILTIN_CTZ = 3, BUILTIN_CTZL = 4, + BUILTIN_CTZLL = 5, BUILTIN_POPCOUNT = 6, BUILTIN_POPCOUNTL = 7, BUILTIN_POPCOUNTLL = 8, BUILTIN_PARITY = 9, + BUILTIN_PARITYL = 10, BUILTIN_PARITYLL = 11, BUILTIN_ABS = 12, BUILTIN_LABS = 13, BUILTIN_LLABS = 14; + + private static IType intType = new CPPBasicType(Kind.eInt, 0); + private static IType longType = new CPPBasicType(Kind.eInt, CPPBasicType.IS_LONG); + private static IType longlongType = new CPPBasicType(Kind.eInt, CPPBasicType.IS_LONG_LONG); + + private short funcId; + + public ExecBuiltin(short funcId) { + this.funcId = funcId; + } + + @Override + public ICPPExecution instantiate(InstantiationContext context, int maxDepth) { + return this; + } + + @Override + public ICPPExecution executeForFunctionCall(ActivationRecord record, ConstexprEvaluationContext context) { + + switch (funcId) { + case BUILTIN_FFS: + return executeBuiltinFfs(record, context, intType); + case BUILTIN_FFSL: + return executeBuiltinFfs(record, context, longType); + case BUILTIN_FFSLL: + return executeBuiltinFfs(record, context, longlongType); + case BUILTIN_CTZ: + return executeBuiltinCtz(record, context, intType); + case BUILTIN_CTZL: + return executeBuiltinCtz(record, context, longType); + case BUILTIN_CTZLL: + return executeBuiltinCtz(record, context, longlongType); + case BUILTIN_POPCOUNT: + return executeBuiltinPopcount(record, context, intType); + case BUILTIN_POPCOUNTL: + return executeBuiltinPopcount(record, context, longType); + case BUILTIN_POPCOUNTLL: + return executeBuiltinPopcount(record, context, longlongType); + case BUILTIN_PARITY: + return executeBuiltinParity(record, context, intType); + case BUILTIN_PARITYL: + return executeBuiltinParity(record, context, longType); + case BUILTIN_PARITYLL: + return executeBuiltinParity(record, context, longlongType); + case BUILTIN_ABS: + return executeBuiltinAbs(record, context, intType); + case BUILTIN_LABS: + return executeBuiltinAbs(record, context, longType); + case BUILTIN_LLABS: + return executeBuiltinAbs(record, context, longlongType); + } + return null; + } + + /* + * Return an execution representing __builtin_ffs or __builtin_ctz + */ + private ICPPExecution executeBuiltinFfsCtz(ActivationRecord record, ConstexprEvaluationContext context, + boolean isCtz, IType argType) { + ICPPEvaluation arg0 = record.getVariable(new CPPBuiltinParameter(null, 0)); + + IValue argValue = arg0.getValue(); + Number numberVal = argValue.numberValue(); + numberVal = Conversions.narrowNumberValue(numberVal, argType); + if (numberVal == null) + return null; + + // __builtin_ffs returns 0 if arg is 0, or 1+count where count is the number of trailing 0 bits + // __builtin_ctz is undefined if arg is 0, or returns count + long arg = numberVal.longValue(); + if (arg == 0) { + if (isCtz) { + return null; + } else { + return new ExecReturn(new EvalFixed(intType, ValueCategory.PRVALUE, IntegralValue.create(0))); + } + } + int count = 0; + while ((arg & 1) == 0) { + arg >>= 1; + count++; + } + int increment = isCtz ? 0 : 1; + return new ExecReturn(new EvalFixed(intType, ValueCategory.PRVALUE, IntegralValue.create(count + increment))); + } + + private ICPPExecution executeBuiltinFfs(ActivationRecord record, ConstexprEvaluationContext context, + IType argType) { + return executeBuiltinFfsCtz(record, context, false /* ffs */, argType); + } + + private ICPPExecution executeBuiltinCtz(ActivationRecord record, ConstexprEvaluationContext context, + IType argType) { + return executeBuiltinFfsCtz(record, context, true /* ctz */, argType); + } + + /* + * Return an execution representing __builtin_popcount + */ + private ICPPExecution executeBuiltinPopcountParity(ActivationRecord record, ConstexprEvaluationContext context, + boolean isParity, IType argType) { + ICPPEvaluation arg0 = record.getVariable(new CPPBuiltinParameter(null, 0)); + + IValue argValue = arg0.getValue(); + Number numberVal = argValue.numberValue(); + numberVal = Conversions.narrowNumberValue(numberVal, argType); + if (numberVal == null) + return null; + + long arg = numberVal.longValue(); + int count = 0; + while (arg != 0) { + if ((arg & 1) != 0) + count++; + arg >>>= 1; + } + if (isParity) { + count = count & 1; + } + return new ExecReturn(new EvalFixed(intType, ValueCategory.PRVALUE, IntegralValue.create(count))); + } + + private ICPPExecution executeBuiltinPopcount(ActivationRecord record, ConstexprEvaluationContext context, + IType argType) { + return executeBuiltinPopcountParity(record, context, false, argType); + } + + private ICPPExecution executeBuiltinParity(ActivationRecord record, ConstexprEvaluationContext context, + IType argType) { + return executeBuiltinPopcountParity(record, context, true, argType); + } + + private ICPPExecution executeBuiltinAbs(ActivationRecord record, ConstexprEvaluationContext context, + IType argType) { + ICPPEvaluation arg0 = record.getVariable(new CPPBuiltinParameter(null, 0)); + + IValue argValue = arg0.getValue(); + Number argNumber = argValue.numberValue(); + argNumber = Conversions.narrowNumberValue(argNumber, argType); + if (argNumber == null) + return null; + + long arg = argNumber.longValue(); + long result = Math.abs(arg); + + return new ExecReturn(new EvalFixed(argType, ValueCategory.PRVALUE, IntegralValue.create(result))); + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + buffer.putShort(ITypeMarshalBuffer.EXEC_BUILTIN); + buffer.putShort(funcId); + } + + public static ICPPExecution unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException { + short funcId = buffer.getShort(); + return new ExecBuiltin(funcId); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecCompoundStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecCompoundStatement.java index a906b88b4c7..bd9b040e8b2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecCompoundStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecCompoundStatement.java @@ -21,6 +21,10 @@ import org.eclipse.core.runtime.CoreException; public class ExecCompoundStatement implements ICPPExecution { private ICPPExecution[] executions; + public ExecCompoundStatement() { + this(new IASTStatement[] {}); + } + private ExecCompoundStatement(ICPPExecution[] executions) { this.executions = executions; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index 218d34adee5..d4b5cac39dc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -123,6 +123,7 @@ public class LookupData extends ScopeLookupData { public ICPPClassType skippedScope; public Object foundItems; public ProblemBinding problem; + public boolean isDestructor; public LookupData(IASTName name) { super(name, true, false); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index f84d285bad6..ebf6c6d1b86 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -68,6 +68,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -945,4 +946,13 @@ public class SemanticUtil { } return result; } + + public static IType applyTypeTransformation(ICPPUnaryTypeTransformation.Operator operator, IType type) { + switch (operator) { + case underlying_type: + return TypeTraits.underlyingType(type); + default: + return null; // shouldn't happen + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index 1ceb1694fc9..5a9f4ab9059 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -135,7 +135,7 @@ public class TemplateArgumentDeduction { break; } - par = CPPTemplates.instantiateType(par, new InstantiationContext(map)); + par = CPPTemplates.instantiateType(par, InstantiationContext.forDeduction(map)); if (!SemanticUtil.isValidType(par)) return false; @@ -352,7 +352,7 @@ public class TemplateArgumentDeduction { return null; IType par = template.getType(); - InstantiationContext context = new InstantiationContext(map); + InstantiationContext context = InstantiationContext.forDeduction(map); par = CPPTemplates.instantiateType(par, context); if (!SemanticUtil.isValidType(par)) return null; @@ -399,7 +399,7 @@ public class TemplateArgumentDeduction { return null; } - InstantiationContext context = new InstantiationContext(map); + InstantiationContext context = InstantiationContext.forDeduction(map); for (int i = 0; i < length; i++) { if (result[i] == null) { final ICPPTemplateParameter tpar = tmplParams[i]; @@ -427,7 +427,7 @@ public class TemplateArgumentDeduction { return null; IType a = SemanticUtil.getSimplifiedType(ftype); - InstantiationContext context = new InstantiationContext(map); + InstantiationContext context = InstantiationContext.forDeduction(map); IType p = CPPTemplates.instantiateType(template.getType(), context); if (!SemanticUtil.isValidType(p)) return null; @@ -572,25 +572,45 @@ public class TemplateArgumentDeduction { return true; } - private static int deduceForPartialOrdering(IType par, IType arg, TemplateArgumentDeduction deduct) + private static int deduceForPartialOrdering(IType parOrig, IType argOrig, TemplateArgumentDeduction deduct) throws DOMException { - par = getNestedType(par, TDEF); - arg = getNestedType(arg, TDEF); + IType parNested = getNestedType(parOrig, TDEF); + IType argNested = getNestedType(argOrig, TDEF); boolean isMoreCVQualified = false; - if (par instanceof ICPPReferenceType && arg instanceof ICPPReferenceType) { - par = getNestedType(par, REF | TDEF); - arg = getNestedType(arg, REF | TDEF); - CVQualifier cvp = getCVQualifier(par); - CVQualifier cva = getCVQualifier(arg); + boolean preferForLValueRef = false; + if (parNested instanceof ICPPReferenceType && argNested instanceof ICPPReferenceType) { + preferForLValueRef = compareRValueRValueTemplateFunctions(parNested, argNested); + parNested = getNestedType(parNested, REF | TDEF); + argNested = getNestedType(argNested, REF | TDEF); + CVQualifier cvp = getCVQualifier(parNested); + CVQualifier cva = getCVQualifier(argNested); isMoreCVQualified = cva.isMoreQualifiedThan(cvp); } - par = getNestedType(par, TDEF | REF | ALLCVQ); - arg = getNestedType(arg, TDEF | REF | ALLCVQ); + parNested = getNestedType(parNested, TDEF | REF | ALLCVQ); + argNested = getNestedType(argNested, TDEF | REF | ALLCVQ); - if (!deduct.fromType(par, arg, false, false)) + if (!deduct.fromType(parNested, argNested, false, false)) return -1; - return isMoreCVQualified ? 1 : 0; + return (isMoreCVQualified || preferForLValueRef) ? 1 : 0; + } + + private static boolean compareRValueRValueTemplateFunctions(final IType f1, final IType f2) { + ICPPReferenceType fstTp = (ICPPReferenceType) f1; + ICPPReferenceType sndTp = (ICPPReferenceType) f2; + + boolean fstRv = fstTp.isRValueReference(); + boolean sndRv = sndTp.isRValueReference(); + + if (fstRv != sndRv) { + return fstRv; + } + + return false; + } + + private static boolean isReferenceType(IType fstSpecP) { + return ICPPReferenceType.class.isAssignableFrom(fstSpecP.getClass()); } /** @@ -759,7 +779,7 @@ public class TemplateArgumentDeduction { private static boolean verifyDeduction(ICPPTemplateParameter[] pars, CPPTemplateParameterMap tpMap, boolean useDefaults) { - InstantiationContext context = new InstantiationContext(tpMap); + InstantiationContext context = InstantiationContext.forDeduction(tpMap); for (ICPPTemplateParameter tpar : pars) { if (tpar.isParameterPack()) { ICPPTemplateArgument[] deducedArgs = tpMap.getPackExpansion(tpar); @@ -1022,7 +1042,7 @@ public class TemplateArgumentDeduction { return true; // An unknown type may match anything. // Verify that the resolved binding matches the argument type. - InstantiationContext context = new InstantiationContext(fDeducedArgs); + InstantiationContext context = InstantiationContext.forDeduction(fDeducedArgs); IBinding binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) p, context); if (binding instanceof ICPPUnknownBinding) return true; // An unknown type may match anything. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeInstantiationRequest.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeInstantiationRequest.java index e667de7196d..4e2cb16f80b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeInstantiationRequest.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeInstantiationRequest.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization; import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext; import org.eclipse.core.runtime.CoreException; @@ -36,7 +37,15 @@ public class TypeInstantiationRequest { public TypeInstantiationRequest(IType type, InstantiationContext context) { this.type = type; - this.parameterMap = context.getParameterMap(); + /* + * If the InstantiationContext was created during template argument deduction, its parameter map + * can be modified later in the deduction process. Since the TypeInstantiationRequest is used + * as a key in various caches, we don't want the map changing after constructing this object, + * so clone the map is such cases. + */ + this.parameterMap = context.isForDeduction() + ? new CPPTemplateParameterMap((CPPTemplateParameterMap) context.getParameterMap()) + : context.getParameterMap(); this.packOffset = context.getPackOffset(); this.contextTypeSpecialization = context.getContextTypeSpecialization(); } @@ -80,7 +89,7 @@ public class TypeInstantiationRequest { return true; if (type1 == null || type2 == null) return false; - return type1.isSameType(type1); + return type1.isSameType(type2); } private boolean equals(ICPPTemplateParameterMap map1, ICPPTemplateParameterMap map2) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java index cbba16a0c70..07b7aee8e91 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java @@ -271,8 +271,15 @@ public class TypeTraits { // 8.1.5.1 p.2 (N4659): The closure type is not an aggregate type. if (classType instanceof CPPClosureType) return false; - if (classType.getBases().length > 0) - return false; + if (classType.getBases().length > 0) { + // c++17 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0017r1.html + for (ICPPBase base : classType.getBases()) { + if (base.isVirtual()) + return false; + if (base.getVisibility() == ICPPBase.v_private || base.getVisibility() == ICPPBase.v_protected) + return false; + } + } ICPPMethod[] methods = classType.getDeclaredMethods(); for (ICPPMethod m : methods) { if (m instanceof ICPPConstructor) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCFunction.java index bc2ab8d1380..74669ea2251 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCFunction.java @@ -83,4 +83,9 @@ class CompositeCFunction extends CompositeCBinding implements IFunction { public boolean isNoReturn() { return ((IFunction) rbinding).isNoReturn(); } + + @Override + public boolean isNoDiscard() { + return ((IFunction) rbinding).isNoDiscard(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java index 37f0da7e435..ab8380c065e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java @@ -45,7 +45,7 @@ import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; public class CompositeCPPClassSpecialization extends CompositeCPPClassType implements ICPPClassSpecialization { private ObjectMap specializationMap; - private final ThreadLocal<Set<IBinding>> fInProgress = new ThreadLocal<Set<IBinding>>() { + private final ThreadLocal<Set<IBinding>> fInProgress = new ThreadLocal<>() { @Override protected Set<IBinding> initialValue() { return new HashSet<>(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java index 2151da243e6..7dccbf0d4fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java @@ -231,4 +231,9 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType public int getVisibility(IBinding member) { return ((ICPPClassType) rbinding).getVisibility(member); } + + @Override + public boolean isNoDiscard() { + return ((ICPPClassType) rbinding).isNoDiscard(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java index 73ec8ab5905..bb7631be278 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java @@ -76,4 +76,9 @@ class CompositeCPPEnumeration extends CompositeCPPBinding implements ICPPEnumera public ICPPScope asScope() { return new CompositeCPPEnumScope(cf, rbinding); } + + @Override + public boolean isNoDiscard() { + return ((ICPPEnumeration) rbinding).isNoDiscard(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunction.java index cf41dbde615..3b8467a5fcf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunction.java @@ -152,4 +152,9 @@ class CompositeCPPFunction extends CompositeCPPBinding implements ICPPFunction, public ICPPExecution getFunctionBodyExecution() { return CPPFunction.getFunctionBodyExecution((ICPPFunction) rbinding); } + + @Override + public boolean isNoDiscard() { + return ((ICPPFunction) rbinding).isNoDiscard(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java index 5c54eaf2687..0fbf4767490 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java @@ -191,6 +191,11 @@ public class CompositeCPPTemplateTemplateParameter extends CompositeCPPBinding } @Override + public boolean isNoDiscard() { + return false; + } + + @Override public int getVisibility(IBinding member) { throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerTask.java index ba297d1e5cf..43a0b68d904 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerTask.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2020 Wind River Systems, Inc. and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -11,9 +11,11 @@ * Contributors: * Markus Schorn - initial API and implementation * IBM Corporation + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.indexer; +import java.text.MessageFormat; import java.text.NumberFormat; import java.util.Collection; import java.util.Iterator; @@ -27,8 +29,6 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import com.ibm.icu.text.MessageFormat; - /** * A task for index updates. * diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/EmptyIterator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/EmptyIterator.java index cf4d1624448..ace153b52d9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/EmptyIterator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/EmptyIterator.java @@ -27,25 +27,16 @@ public final class EmptyIterator<T> implements Iterator<T> { private EmptyIterator() { } - /* (non-Javadoc) - * @see java.util.Iterator#hasNext() - */ @Override public final boolean hasNext() { return false; } - /* (non-Javadoc) - * @see java.util.Iterator#next() - */ @Override public final T next() { throw new NoSuchElementException(); } - /* (non-Javadoc) - * @see java.util.Iterator#remove() - */ @Override public final void remove() { throw new UnsupportedOperationException(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/FileContentProviderAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/FileContentProviderAdapter.java index 9f0d7093dc3..0db29107783 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/FileContentProviderAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/FileContentProviderAdapter.java @@ -49,8 +49,7 @@ public class FileContentProviderAdapter extends InternalFileContentProvider { private FileContentProviderAdapter(AbstractCodeReaderFactory factory) { fDelegate = factory; - setIncludeResolutionHeuristics( - (IIncludeFileResolutionHeuristics) factory.getAdapter(IIncludeFileResolutionHeuristics.class)); + setIncludeResolutionHeuristics(factory.getAdapter(IIncludeFileResolutionHeuristics.class)); } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.java index 5aa7f207bb4..fc85d3662a6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2014 IBM Corporation and others. + * Copyright (c) 2004, 2020 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,16 +10,16 @@ * * Contributors: * Andrew Niefer (IBM Corporation) - Initial API and implementation + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.parser; +import java.text.MessageFormat; import java.util.MissingResourceException; import java.util.ResourceBundle; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; -import com.ibm.icu.text.MessageFormat; - public class ParserMessages { private static final String BUNDLE_NAME = ParserMessages.class.getName(); private static ResourceBundle resourceBundle; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties index b867ea44e76..bc9e25aeab0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties @@ -30,6 +30,7 @@ ScannerProblemFactory.error.preproc.macroPasting=Invalid use of macro pasting in ScannerProblemFactory.error.preproc.missingRParen=missing '')'' in parameter list of macro: {0} ScannerProblemFactory.error.preproc.invalidVaArgs=__VA_ARGS__ can only appear in the expansion of a variadic macro\u0020 ScannerProblemFactory.error.preproc.multipleUserDefinedLiteralSuffixesOnStringLiteral=Multiple user-defined suffixes found when concatenating string literals +ScannerProblemFactory.error.preproc.invalidUsageOutsidePreprocDirective="{0}" can only appear in a preprocessor directive ScannerProblemFactory.error.scanner.invalidEscapeChar=Invalid escape character encountered\u0020 ScannerProblemFactory.error.scanner.unboundedString=Unbounded string encountered\u0020 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java index ea094e0b023..72a3e4d9057 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java @@ -199,13 +199,12 @@ class ASTBuiltinName extends ASTPreprocessorDefinition implements IAdaptable { } @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object getAdapter(Class adapter) { + public <T> T getAdapter(Class<T> adapter) { if (adapter.isAssignableFrom(ASTBuiltinName.class)) { - return this; + return adapter.cast(this); } if (fOriginalDefinition != null && adapter.isAssignableFrom(fOriginalDefinition.getClass())) { - return fOriginalDefinition; + return adapter.cast(fOriginalDefinition); } return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java index 4b82a263411..4a8762f0af7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java @@ -92,6 +92,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { public static final int tNOSPACE = IToken.FIRST_RESERVED_PREPROCESSOR + 4; public static final int tMACRO_PARAMETER = IToken.FIRST_RESERVED_PREPROCESSOR + 5; public static final int t__HAS_FEATURE = IToken.FIRST_RESERVED_PREPROCESSOR + 6; + public static final int t__HAS_INCLUDE = IToken.FIRST_RESERVED_PREPROCESSOR + 7; + public static final int t__HAS_INCLUDE_NEXT = IToken.FIRST_RESERVED_PREPROCESSOR + 8; private static final int ORIGIN_PREPROCESSOR_DIRECTIVE = OffsetLimitReachedException.ORIGIN_PREPROCESSOR_DIRECTIVE; private static final int ORIGIN_INACTIVE_CODE = OffsetLimitReachedException.ORIGIN_INACTIVE_CODE; @@ -103,7 +105,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { Integer.toString(getCDTVersion()).toCharArray()); private static final ObjectStyleMacro __cplusplus = new ObjectStyleMacro("__cplusplus".toCharArray(), //$NON-NLS-1$ "201103L".toCharArray()); //$NON-NLS-1$ - private static final ObjectStyleMacro __STDC__ = new ObjectStyleMacro("__STDC__".toCharArray(), ONE); //$NON-NLS-1$ private static final ObjectStyleMacro __STDC_HOSTED__ = new ObjectStyleMacro("__STDC_HOSTED__".toCharArray(), ONE); //$NON-NLS-1$ private static final ObjectStyleMacro __STDC_VERSION__ = new ObjectStyleMacro("__STDC_VERSION__".toCharArray(), //$NON-NLS-1$ "199901L".toCharArray()); //$NON-NLS-1$ @@ -178,13 +179,19 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { T checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath); } - final private IIncludeFileTester<InternalFileContent> createCodeReaderTester = new IIncludeFileTester<InternalFileContent>() { + final private IIncludeFileTester<InternalFileContent> createCodeReaderTester = new IIncludeFileTester<>() { @Override public InternalFileContent checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) { 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) { + CCorePlugin.log(e); + } + fc = new InternalFileContent(path, InclusionKind.SKIP_PRAGMA_ONCE_FILE, significantMacros); } else { fc = fFileContentProvider.getContentForInclusion(path, fMacroDictionaryFacade); } @@ -206,7 +213,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { } } - final private IIncludeFileTester<IncludeResolution> createPathTester = new IIncludeFileTester<IncludeResolution>() { + final private IIncludeFileTester<IncludeResolution> createPathTester = new IIncludeFileTester<>() { @Override public IncludeResolution checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) { if (fFileContentProvider.getInclusionExists(path)) { @@ -507,7 +514,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { private void setupMacroDictionary(IScannerExtensionConfiguration config, IScannerInfo info, ParserLanguage lang) { // Built-in macros fMacroDictionary.put(__CDT_PARSER__.getNameCharArray(), __CDT_PARSER__); - fMacroDictionary.put(__STDC__.getNameCharArray(), __STDC__); fMacroDictionary.put(__FILE__.getNameCharArray(), __FILE__); fMacroDictionary.put(__DATE__.getNameCharArray(), __DATE__); fMacroDictionary.put(__TIME__.getNameCharArray(), __TIME__); @@ -1325,6 +1331,11 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { } + InternalFileContent findInclusion(final String includeDirective, final boolean quoteInclude, + final boolean includeNext) { + return findInclusion(includeDirective, quoteInclude, includeNext, getCurrentFilename(), createCodeReaderTester); + } + private <T> T findInclusion(final String includeDirective, final boolean quoteInclude, final boolean includeNext, final String currentFile, final IIncludeFileTester<T> tester) { T reader = null; @@ -1785,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()) { @@ -1807,10 +1826,11 @@ 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); } - private char[] extractHeaderName(final char[] image, final char startDelim, final char endDelim, int[] offsets) { + char[] extractHeaderName(final char[] image, final char startDelim, final char endDelim, int[] offsets) { char[] headerName; int start = 0; int length = image.length; @@ -2126,9 +2146,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { * If applicable the macro is expanded and the resulting tokens are put onto a new context. * @param identifier the token where macro expansion may occur. * @param lexer the input for the expansion. - * @param stopAtNewline whether or not tokens to be read are limited to the current line. - * @param isPPCondition whether the expansion is inside of a preprocessor condition. This - * implies a specific handling for the defined token. */ private boolean expandMacro(final Token identifier, Lexer lexer, int options, boolean withinExpansion) throws OffsetLimitReachedException { @@ -2143,7 +2160,24 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { identifier.setType(t__HAS_FEATURE); return false; } + if (CharArrayUtils.equals(name, Keywords.c__HAS_INCLUDE)) { + identifier.setType(t__HAS_INCLUDE); + return false; + } + if (CharArrayUtils.equals(name, Keywords.c__HAS_INCLUDE_NEXT)) { + identifier.setType(t__HAS_INCLUDE_NEXT); + return false; + } + } + + // These should not expand as macros and are not allowed outside #if, #ifdef + if (CharArrayUtils.equals(name, Keywords.c__HAS_INCLUDE) + || CharArrayUtils.equals(name, Keywords.c__HAS_INCLUDE_NEXT)) { + handleProblem(IProblem.PREPROCESSOR_INVALID_USE_OUTSIDE_PREPROCESSOR_DIRECTIVE, name, + identifier.getOffset(), identifier.getEndOffset()); + return false; } + PreprocessorMacro macro = fMacroDictionary.get(name); if (macro == null) { if (reportSignificant && (options & IGNORE_UNDEFINED_SIGNIFICANT_MACROS) == 0) @@ -2324,6 +2358,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { addTypeTraitPrimitive("is_trivially_copyable", GCCKeywords.cp__is_trivially_copyable); addTypeTraitPrimitive("is_union", GCCKeywords.cp__is_union); addTypeTraitPrimitive("underlying_type", GCCKeywords.cp__underlying_type); + + // TODO: If at some point we add support for __has_builtin, "__integer_pack" + // should be added to the list of supported builtins. } return sSupportedFeatures; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ExpressionEvaluator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ExpressionEvaluator.java index 405010c737a..8e589416f21 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ExpressionEvaluator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ExpressionEvaluator.java @@ -265,6 +265,10 @@ public class ExpressionEvaluator { return handleDefined(); case CPreprocessor.t__HAS_FEATURE: return handleHasFeature(); + case CPreprocessor.t__HAS_INCLUDE: + return handleHasInclude(false); + case CPreprocessor.t__HAS_INCLUDE_NEXT: + return handleHasInclude(true); case IToken.tLPAREN: consume(); long r1 = expression(); @@ -350,6 +354,51 @@ public class ExpressionEvaluator { return supported ? 1 : 0; } + private long handleHasInclude(boolean isIncludeNext) throws EvalException { + consume(); // '__has_include' + if (LA() != IToken.tLPAREN) { + throw new EvalException(IProblem.SCANNER_EXPRESSION_SYNTAX_ERROR, null); + } + consume(); // opening parenthesis + + // We don't have a tSYSTEM_HEADER_NAME or tQUOTED_HEADER_NAME token type here, these only get created when + // executing an include directive. In the case of a tSTRING, we only have to extract the header name from the + // quotes (extractHeaderName) but for system header, we have to reassemble the string by concatenating the + // tokens. + // A possibly more elegant solution could be to generate tSYSTEM_HEADER_NAME or tQUOTED_HEADER_NAME (during + // internalFetchToken?) but this is more ambitious and intrusive (more refactoring), especially considering + // various cases like macro expansion. + String headerName; + boolean quoteInclude = false; + if (LA() == IToken.tLT) { + headerName = ""; //$NON-NLS-1$ + while (fTokens.getType() != IToken.tGT) { + if (fTokens.getType() == IToken.tEND_OF_INPUT) { + throw new EvalException(IProblem.SCANNER_UNBOUNDED_STRING, null); + } + headerName += fTokens.getImage(); + consume(); + } + consume(); + headerName += ">"; //$NON-NLS-1$ + headerName = new String(fPreprocessor.extractHeaderName(headerName.toCharArray(), '<', '>', new int[2])); + } else if (LA() == IToken.tSTRING) { + quoteInclude = true; + headerName = new String(fPreprocessor.extractHeaderName(fTokens.getCharImage(), '"', '"', new int[2])); + consume(); + } else { + throw new EvalException(IProblem.SCANNER_EXPRESSION_SYNTAX_ERROR, null); + } + + if (LA() != IToken.tRPAREN) { + throw new EvalException(IProblem.SCANNER_MISSING_R_PAREN, null); + } + consume(); // closing parenthesis + + boolean includePathExists = fPreprocessor.findInclusion(headerName, quoteInclude, isIncludeNext) != null; + return includePathExists ? 1 : 0; + } + private int LA() { return fTokens.getType(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java index 0d78aa1dc89..e5889f72936 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContent.java @@ -33,6 +33,11 @@ public class InternalFileContent extends FileContent { */ 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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java index a292c8bd945..04a7e57bb2e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java @@ -376,6 +376,12 @@ public class MacroExpander { t.setType(CPreprocessor.t__HAS_FEATURE); result.append(t); protect = true; + } else if (protectIntrinsics && Arrays.equals(image, Keywords.c__HAS_INCLUDE)) { + t.setType(CPreprocessor.t__HAS_INCLUDE); + result.append(t); + } else if (protectIntrinsics && Arrays.equals(image, Keywords.c__HAS_INCLUDE_NEXT)) { + t.setType(CPreprocessor.t__HAS_INCLUDE_NEXT); + result.append(t); } else if (macro == null || (macro.isFunctionStyle() && !input.findLParenthesis())) { // Tricky: Don't mark function-style macros if you don't find the left parenthesis if (fReportMacros != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/PreprocessorMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/PreprocessorMacro.java index 2549b2a1c09..e9976f203df 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/PreprocessorMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/PreprocessorMacro.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2015 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2020 Wind River Systems, Inc. and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,9 +10,11 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.parser.scanner; +import java.text.DateFormatSymbols; import java.util.Calendar; import org.eclipse.cdt.core.dom.ILinkage; @@ -25,8 +27,6 @@ import org.eclipse.cdt.core.parser.OffsetLimitReachedException; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions; -import com.ibm.icu.text.DateFormatSymbols; - /** * Models macros used by the preprocessor * @since 5.0 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/SignificantMacros.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/SignificantMacros.java index 4d9e8a807b8..80e55a89f46 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/SignificantMacros.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/SignificantMacros.java @@ -33,7 +33,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils; public class SignificantMacros implements ISignificantMacros { public static final char[] DEFINED = { 0 }; public static final char[] UNDEFINED = { 1 }; - private static final Comparator<char[]> SORTER = new Comparator<char[]>() { + private static final Comparator<char[]> SORTER = new Comparator<>() { @Override public int compare(char[] s1, char[] s2) { return CharArrayUtils.compare(s1, s2); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/KeywordSets.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/KeywordSets.java index f2edfaf1f96..8fe672ed025 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/KeywordSets.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/KeywordSets.java @@ -416,6 +416,7 @@ public class KeywordSets { ALL_CPP.add(Keywords.EXPORT); ALL_CPP.add(Keywords.EXTERN); ALL_CPP.add(Keywords.FALSE); + ALL_CPP.add(Keywords.FINAL); ALL_CPP.add(Keywords.FLOAT); ALL_CPP.add(Keywords.FOR); ALL_CPP.add(Keywords.FRIEND); @@ -434,6 +435,7 @@ public class KeywordSets { ALL_CPP.add(Keywords.OPERATOR); ALL_CPP.add(Keywords.OR); ALL_CPP.add(Keywords.OR_EQ); + ALL_CPP.add(Keywords.OVERRIDE); ALL_CPP.add(Keywords.PRIVATE); ALL_CPP.add(Keywords.PROTECTED); ALL_CPP.add(Keywords.PUBLIC); @@ -512,6 +514,7 @@ public class KeywordSets { KEYWORDS_CPP.add(Keywords.EXPORT); KEYWORDS_CPP.add(Keywords.EXTERN); KEYWORDS_CPP.add(Keywords.FALSE); + KEYWORDS_CPP.add(Keywords.FINAL); KEYWORDS_CPP.add(Keywords.FLOAT); KEYWORDS_CPP.add(Keywords.FOR); KEYWORDS_CPP.add(Keywords.FRIEND); @@ -530,6 +533,7 @@ public class KeywordSets { KEYWORDS_CPP.add(Keywords.OPERATOR); KEYWORDS_CPP.add(Keywords.OR); KEYWORDS_CPP.add(Keywords.OR_EQ); + KEYWORDS_CPP.add(Keywords.OVERRIDE); KEYWORDS_CPP.add(Keywords.PRIVATE); KEYWORDS_CPP.add(Keywords.PROTECTED); KEYWORDS_CPP.add(Keywords.PUBLIC); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/util/Profiler.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/util/Profiler.java index 5dd2cdafa0d..eb55a4e6cb5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/util/Profiler.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/util/Profiler.java @@ -137,7 +137,7 @@ public class Profiler { Profiler profiler = threadProfiler.get(); if (profiler != null) { List<Map.Entry<String, Timer>> list = new ArrayList<>(profiler.timers.entrySet()); - Comparator<Map.Entry<String, Timer>> c = new Comparator<Map.Entry<String, Timer>>() { + Comparator<Map.Entry<String, Timer>> c = new Comparator<>() { @Override public int compare(Entry<String, Timer> o1, Entry<String, Timer> o2) { long diff = o2.getValue().getElapsedTime() - o1.getValue().getElapsedTime(); @@ -153,7 +153,7 @@ public class Profiler { if (!profiler.counters.isEmpty()) { List<Map.Entry<String, int[]>> keyList = new ArrayList<>(profiler.counters.entrySet()); - Comparator<Map.Entry<String, int[]>> c2 = new Comparator<Map.Entry<String, int[]>>() { + Comparator<Map.Entry<String, int[]>> c2 = new Comparator<>() { @Override public int compare(Entry<String, int[]> o1, Entry<String, int[]> o2) { return o2.getValue()[0] - o1.getValue()[0]; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/CModelListener.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/CModelListener.java index 5b750f5d232..364b6519edb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/CModelListener.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/CModelListener.java @@ -42,7 +42,7 @@ public class CModelListener implements IElementChangedListener, IResourceChangeL public static boolean sSuppressUpdateOfLastRecentlyUsed = false; private PDOMManager fManager; - private final LinkedHashMap<ITranslationUnit, ITranslationUnit> fLRUs = new LinkedHashMap<ITranslationUnit, ITranslationUnit>( + private final LinkedHashMap<ITranslationUnit, ITranslationUnit> fLRUs = new LinkedHashMap<>( UPDATE_LR_CHANGED_FILES_COUNT, 0.75f, true) { @Override protected boolean removeEldestEntry(Map.Entry<ITranslationUnit, ITranslationUnit> eldest) { 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 086d14bb9d7..4cff50e8adb 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 @@ -302,10 +302,19 @@ public class PDOM extends PlatformObject implements IPDOM { * * CDT 9.9 development (version not supported on the 9.8.x branch) * 215.0 - Corruption due to wrong record size in field/variable template partial specialization, bug 549028. + * + * CDT 9.12 development (version not supported on the 9.11.x branch) + * 216.0 - Added nodiscard function information, bug 534420 + * 217.0 - Added nodiscard class/struct information, bug 534420 + * 218.0 - Added nodiscard enums information, bug 534420 + * 219.0 - Fix enums nodiscard information in the index from 8 byte to 1 byte, bug 534420 + * + * CDT 10.4 development + * 220.0 - Changed marshalling of CPPBasicType to store new "from literal" flag, bug 573764 */ - private static final int MIN_SUPPORTED_VERSION = version(215, 0); - private static final int MAX_SUPPORTED_VERSION = version(215, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(215, 0); + private static final int MIN_SUPPORTED_VERSION = version(220, 0); + private static final int MAX_SUPPORTED_VERSION = version(220, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(220, 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/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java index 0a13c206af9..868780685ae 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2018 QNX Software Systems and others. + * Copyright (c) 2005, 2020 QNX Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -18,6 +18,7 @@ * Marc-Andre Laperle * Martin Oberhuber (Wind River) - [397652] fix up-to-date check for PDOM * IBM Corporation + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom; @@ -26,6 +27,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; @@ -117,9 +120,6 @@ import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChange import org.eclipse.core.runtime.preferences.IPreferencesService; import org.eclipse.core.runtime.preferences.InstanceScope; -import com.ibm.icu.text.MessageFormat; -import com.ibm.icu.text.SimpleDateFormat; - /** * Manages PDOM updates and events associated with them. Provides methods for index access. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java index b678934cb27..b8731ca64fb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java @@ -250,10 +250,9 @@ public class PDOMProxy implements IPDOM { fDelegate.resetCacheCounters(); } - @SuppressWarnings({ "rawtypes", "unchecked" }) - public synchronized Object getAdapter(Class adapter) { + public synchronized <T> T getAdapter(Class<T> adapter) { if (adapter.isAssignableFrom(PDOMProxy.class)) { - return this; + return adapter.cast(this); } return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java index 2c6c7d28e82..1f5d80e459a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2016 QNX Software Systems and others. + * Copyright (c) 2005, 2020 QNX Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -12,16 +12,17 @@ * QNX - Initial API and implementation * Andrew Ferguson (Symbian) - Provide B-tree deletion routine * Markus Schorn (Wind River Systems) + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.db; +import java.text.MessageFormat; + import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import com.ibm.icu.text.MessageFormat; - /** * @author Doug Schaefer */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java index c3ff517248e..f138c44c9da 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2015 QNX Software Systems and others. + * Copyright (c) 2005, 2020 QNX Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -14,6 +14,7 @@ * Markus Schorn (Wind River Systems) * IBM Corporation * Sergey Prigogin (Google) + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.db; @@ -28,6 +29,7 @@ import java.nio.ByteBuffer; import java.nio.channels.ClosedByInterruptException; import java.nio.channels.ClosedChannelException; import java.nio.channels.FileChannel; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -38,8 +40,6 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.osgi.util.NLS; -import com.ibm.icu.text.MessageFormat; - /** * Database encapsulates access to a flat binary format file with a memory-manager-like API for * obtaining and releasing areas of storage (memory). diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java index 18162597b25..97a7ed6f697 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java @@ -578,6 +578,11 @@ public class PDOMASTAdapter { public ICPPScope asScope() { return ((ICPPEnumeration) fDelegate).asScope(); } + + @Override + public boolean isNoDiscard() { + return ((ICPPEnumeration) fDelegate).isNoDiscard(); + } } private static class AnonymousClassType extends AnonymousCPPBinding implements ICPPClassType { @@ -669,6 +674,11 @@ public class PDOMASTAdapter { public int getVisibility(IBinding member) { return ((ICPPClassType) fDelegate).getVisibility(member); } + + @Override + public boolean isNoDiscard() { + return ((ICPPClassType) fDelegate).isNoDiscard(); + } } private static class AnonymousClassSpecialization extends AnonymousClassType implements ICPPClassSpecialization { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java index 170f025f470..42615e71cc4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java @@ -87,7 +87,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage * The set of types currently being loaded from the index on each thread, represented as record numbers. * This is used to guard against infinite recursion while loading types. */ - private static final ThreadLocal<Set<Long>> fLoadTypeInProgress = new ThreadLocal<Set<Long>>() { + private static final ThreadLocal<Set<Long>> fLoadTypeInProgress = new ThreadLocal<>() { @Override protected Set<Long> initialValue() { return new HashSet<>(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java index fcae57b3e1d..e029f880780 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java @@ -373,10 +373,9 @@ public class PDOMMacro implements IIndexMacro, IPDOMBinding { } @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Object getAdapter(Class adapter) { + public <T> T getAdapter(Class<T> adapter) { if (adapter.isAssignableFrom(PDOMMacro.class)) { - return this; + return adapter.cast(this); } return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroContainer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroContainer.java index 266079a3009..817de429e5f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroContainer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroContainer.java @@ -171,10 +171,9 @@ public class PDOMMacroContainer extends PDOMNamedNode implements IIndexMacroCont } @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Object getAdapter(Class adapter) { + public <T> T getAdapter(Class<T> adapter) { if (adapter.isAssignableFrom(PDOMMacroContainer.class)) { - return this; + return adapter.cast(this); } return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java index 9f73005f040..f8ac35b883f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java @@ -56,6 +56,7 @@ public final class PDOMName implements IIndexFragmentName { public static final int IS_FRIEND_SPEC = 0x08; public static final int IS_INLINE_NAMESPACE = 0x0C; public static final int COULD_BE_POLYMORPHIC_METHOD_CALL = 0x10; + //TODO We haven't got any flag for "unknown" access, we should add it to the index public static final int READ_ACCESS = 0x20; public static final int WRITE_ACCESS = 0x40; // Whether this name is a potential match for its binding, rather than an exact match. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCAnnotations.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCAnnotations.java index e842e2aeb81..64da027c55a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCAnnotations.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCAnnotations.java @@ -32,6 +32,9 @@ class PDOMCAnnotations { private static final int NO_RETURN_OFFSET = 4; private static final int REGISTER_OFFSET = 5; private static final int AUTO_OFFSET = 6; + private static final int NO_DISCARD_OFFSET = 7; + //NOTE: we are writing these annotations on a "byte" so if we need + //to add another value we need to use at least a short. /** * Encodes annotations applicable to functions. @@ -55,6 +58,8 @@ class PDOMCAnnotations { annotation |= 1 << REGISTER_OFFSET; if (function.isAuto()) annotation |= 1 << AUTO_OFFSET; + if (function.isNoDiscard()) + annotation |= 1 << NO_DISCARD_OFFSET; return annotation; } @@ -115,6 +120,13 @@ class PDOMCAnnotations { } /** + * Checks if the "no discard" annotation is set. + */ + public static boolean isNoDiscardFunction(short annotation) { + return (annotation & (1 << NO_DISCARD_OFFSET)) != 0; + } + + /** * Checks if the "register" annotation is set. */ public static boolean isRegister(byte annotation) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java index 5230308ea5f..07ddfcffbda 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java @@ -208,4 +208,9 @@ class PDOMCFunction extends PDOMBinding implements IFunction { public IScope getFunctionScope() { return null; } + + @Override + public boolean isNoDiscard() { + return PDOMCAnnotations.isNoDiscardFunction(getAnnotations()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java index bfe51cec7a5..26cdd781a7a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java @@ -15,6 +15,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.c; +import java.util.Optional; + import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -138,7 +140,11 @@ class PDOMCVariable extends PDOMBinding implements IVariable { @Override public int getAdditionalNameFlags(int standardFlags, IASTName name) { if ((standardFlags & PDOMName.IS_REFERENCE) == PDOMName.IS_REFERENCE) { - return CVariableReadWriteFlags.getReadWriteFlags(name); + Optional<Integer> res = CVariableReadWriteFlags.getReadWriteFlags(name); + if (!res.isPresent()) { + return PDOMName.WRITE_ACCESS | PDOMName.READ_ACCESS; + } + return res.get(); } return 0; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPAnnotations.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPAnnotations.java index c7c020c36b5..709f9bc84be 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPAnnotations.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPAnnotations.java @@ -45,6 +45,7 @@ class PDOMCPPAnnotations { private static final int PARAMETER_PACK_OFFSET = 7; private static final int DELETED_OFFSET = 8; private static final int NO_RETURN_OFFSET = 9; + private static final int NO_DISCARD_OFFSET = 10; // Method annotations that don't fit on the first 16 bits of annotations. private static final int VIRTUAL_OFFSET = 0; @@ -82,6 +83,8 @@ class PDOMCPPAnnotations { annotation |= 1 << PARAMETER_PACK_OFFSET; if (function.isDeleted()) annotation |= 1 << DELETED_OFFSET; + if (function.isNoDiscard()) + annotation |= 1 << NO_DISCARD_OFFSET; return annotation; } @@ -227,6 +230,13 @@ class PDOMCPPAnnotations { } /** + * Checks if the "no discard" annotation is set. + */ + public static boolean isNoDiscardFunction(short annotation) { + return (annotation & (1 << NO_DISCARD_OFFSET)) != 0; + } + + /** * Checks if the "virtual" annotation is set. */ public static boolean isVirtualMethod(byte annotation) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java index a1161ad8cae..9e9364d6c56 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java @@ -72,10 +72,11 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization private static final byte FLAGS_FINAL = 0x01; private static final byte FLAGS_HAS_OWN_SCOPE = 0x02; + private static final byte FLAGS_NODISCARD = 0x03; private volatile ICPPClassScope fScope; private ObjectMap specializationMap; // Obtained from the synchronized PDOM cache. - private final ThreadLocal<Set<IBinding>> fInProgress = new ThreadLocal<Set<IBinding>>() { + private final ThreadLocal<Set<IBinding>> fInProgress = new ThreadLocal<>() { @Override protected Set<IBinding> initialValue() { return new HashSet<>(); @@ -508,6 +509,16 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization } } + @Override + public boolean isNoDiscard() { + try { + return (getFlags() & FLAGS_NODISCARD) != 0; + } catch (CoreException e) { + CCorePlugin.log(e); + return false; + } + } + private boolean hasOwnScope() throws CoreException { return (getFlags() & FLAGS_HAS_OWN_SCOPE) != 0; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index 1f2e920a8ff..2d5447c2c4e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -60,8 +60,9 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO private static final int ANONYMOUS = KEY + 1; // byte private static final int FINAL = ANONYMOUS + 1; // byte private static final int VISIBLE_TO_ADL_ONLY = FINAL + 1; // byte + private static final int NO_DISCARD = VISIBLE_TO_ADL_ONLY + 1; // byte @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = VISIBLE_TO_ADL_ONLY + 1; + protected static final int RECORD_SIZE = NO_DISCARD + 1; private PDOMCPPClassScope fScope; // No need for volatile, all fields of PDOMCPPClassScope are final. @@ -73,6 +74,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO setAnonymous(classType); setFinal(classType); setVisibleToAdlOnly(visibleToAdlOnly); + setNoDiscard(classType); // Linked list is initialized by storage being zero'd by malloc. } @@ -97,6 +99,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO setKind(ct); setAnonymous(ct); setFinal(ct); + setNoDiscard(ct); super.update(linkage, newBinding); } } @@ -113,6 +116,10 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO getDB().putByte(record + FINAL, (byte) (ct.isFinal() ? 1 : 0)); } + private void setNoDiscard(ICPPClassType ct) throws CoreException { + getDB().putByte(record + NO_DISCARD, (byte) (ct.isNoDiscard() ? 1 : 0)); + } + @Override public void setVisibleToAdlOnly(boolean visibleToAdlOnly) throws CoreException { getDB().putByte(record + VISIBLE_TO_ADL_ONLY, (byte) (visibleToAdlOnly ? 1 : 0)); @@ -280,6 +287,16 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO } @Override + public boolean isNoDiscard() { + try { + return getDB().getByte(record + NO_DISCARD) != 0; + } catch (CoreException e) { + CCorePlugin.log(e); + return false; + } + } + + @Override public boolean isVisibleToAdlOnly() { try { return getDB().getByte(record + VISIBLE_TO_ADL_ONLY) != 0; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java index dc59848d72c..2319f9c6110 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java @@ -51,6 +51,9 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD private static final int OFFSET_FIXED_TYPE = OFFSET_MAX_VALUE + 8; private static final int OFFSET_FLAGS = OFFSET_FIXED_TYPE + Database.TYPE_SIZE; + private static final byte FLAG_SCOPED = 0x1; + private static final byte FLAG_NODISCARD = 0x2; + @SuppressWarnings("hiding") protected static final int RECORD_SIZE = OFFSET_FLAGS + 1; @@ -75,7 +78,15 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD private void storeProperties(ICPPEnumeration enumeration) throws CoreException { final Database db = getDB(); - db.putByte(record + OFFSET_FLAGS, enumeration.isScoped() ? (byte) 1 : (byte) 0); + byte flags = 0; + if (enumeration.isScoped()) { + flags |= FLAG_SCOPED; + } + if (enumeration.isNoDiscard()) { + flags |= FLAG_NODISCARD; + } + + db.putByte(record + OFFSET_FLAGS, flags); getLinkage().storeType(record + OFFSET_FIXED_TYPE, enumeration.getFixedType()); @@ -188,7 +199,18 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD @Override public boolean isScoped() { try { - return getDB().getByte(record + OFFSET_FLAGS) != 0; + byte flags = getDB().getByte(record + OFFSET_FLAGS); + return (flags & FLAG_SCOPED) != 0; + } catch (CoreException e) { + return false; + } + } + + @Override + public boolean isNoDiscard() { + try { + byte flags = getDB().getByte(record + OFFSET_FLAGS); + return (flags & FLAG_NODISCARD) != 0; } catch (CoreException e) { return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java index 3bda300c388..2208f786de3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java @@ -51,7 +51,8 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization private static final int OFFSET_MIN_VALUE = OFFSET_ENUMERATOR_LIST + Database.PTR_SIZE; private static final int OFFSET_MAX_VALUE = OFFSET_MIN_VALUE + 8; private static final int OFFSET_FIXED_TYPE = OFFSET_MAX_VALUE + 8; - private static final int OFFSET_FLAGS = OFFSET_FIXED_TYPE + Database.TYPE_SIZE; + private static final int OFFSET_NO_DISCARD = OFFSET_FIXED_TYPE + 8; + private static final int OFFSET_FLAGS = OFFSET_NO_DISCARD + Database.TYPE_SIZE; @SuppressWarnings("hiding") protected static final int RECORD_SIZE = OFFSET_FLAGS + 1; @@ -84,6 +85,7 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization private void storeProperties(ICPPEnumeration enumeration) throws CoreException { final Database db = getDB(); db.putByte(record + OFFSET_FLAGS, enumeration.isScoped() ? (byte) 1 : (byte) 0); + db.putByte(record + OFFSET_NO_DISCARD, enumeration.isNoDiscard() ? (byte) 1 : (byte) 0); getLinkage().storeType(record + OFFSET_FIXED_TYPE, enumeration.getFixedType()); @@ -203,6 +205,15 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization } @Override + public boolean isNoDiscard() { + try { + return getDB().getByte(record + OFFSET_NO_DISCARD) != 0; + } catch (CoreException e) { + return false; + } + } + + @Override public IType getFixedType() { if (fFixedType == ProblemBinding.NOT_INITIALIZED) { fFixedType = loadFixedType(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java index 6797e525149..01e8334a218 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java @@ -449,4 +449,9 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl return null; } } + + @Override + public boolean isNoDiscard() { + return PDOMCPPAnnotations.isNoDiscardFunction(getAnnotations()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java index 9b047058a57..6f62bec830b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java @@ -342,4 +342,9 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization return null; } } + + @Override + public boolean isNoDiscard() { + return PDOMCPPAnnotations.isNoDiscardFunction(getAnnotations()); + } } 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 05b9367d2f2..991f3ef73eb 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 @@ -143,6 +143,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnaryTypeID; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecBreak; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecBuiltin; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecCase; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecCompoundStatement; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecConstructorChain; @@ -1270,8 +1271,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { if (owner instanceof IFunction) { boolean isTemplateParameter = binding instanceof ICPPTemplateParameter; boolean ownerIsConstexprFunc = owner instanceof ICPPFunction && ((ICPPFunction) owner).isConstexpr(); - boolean isVariableOrTypedef = binding instanceof ICPPVariable || binding instanceof ITypedef; - if (!isTemplateParameter && !(ownerIsConstexprFunc && isVariableOrTypedef)) { + boolean isVariableOrType = binding instanceof ICPPVariable || binding instanceof IType; + if (!isTemplateParameter && !(ownerIsConstexprFunc && isVariableOrType)) { return null; } } @@ -1771,6 +1772,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return ExecConstructorChain.unmarshal(firstBytes, buffer); case ITypeMarshalBuffer.EXEC_INCOMPLETE: return ExecIncomplete.unmarshal(firstBytes, buffer); + case ITypeMarshalBuffer.EXEC_BUILTIN: + return ExecBuiltin.unmarshal(firstBytes, buffer); } throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal an execution, first bytes=" + firstBytes)); //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java index b33a90157cc..5c8e1a76715 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java @@ -350,6 +350,11 @@ public class PDOMCPPTemplateTemplateParameter extends PDOMCPPBinding implements } @Override + public boolean isNoDiscard() { + return false; + } + + @Override public ICPPTemplateParameter adaptTemplateParameter(ICPPTemplateParameter param) { int pos = param.getParameterPosition(); ICPPTemplateParameter[] pars = getTemplateParameters(); 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 6f02c5b78ee..af083b4f944 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 @@ -15,6 +15,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; +import java.util.Optional; + import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -162,7 +164,11 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable { @Override public int getAdditionalNameFlags(int standardFlags, IASTName name) { if ((standardFlags & PDOMName.IS_REFERENCE) == PDOMName.IS_REFERENCE) { - return CPPVariableReadWriteFlags.getReadWriteFlags(name); + Optional<Integer> res = CPPVariableReadWriteFlags.getReadWriteFlags(name); + if (!res.isPresent()) { + return PDOMName.READ_ACCESS | PDOMName.WRITE_ACCESS; + } + return res.get(); } return 0; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/CLIUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/CLIUtil.java index fb4e8167288..4f5f30acc3b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/CLIUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/CLIUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Symbian Software Systems and others. + * Copyright (c) 2007, 2020 Symbian Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -9,10 +9,12 @@ * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Andrew Ferguson (Symbian) - Initial implementation + * Andrew Ferguson (Symbian) - Initial implementation + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.export; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -21,8 +23,6 @@ import java.util.Map; import org.eclipse.cdt.core.index.export.Messages; import org.eclipse.core.runtime.CoreException; -import com.ibm.icu.text.MessageFormat; - /** * Helper methods for command-line options * <br> diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java index 37cd352c6eb..fb4b4a8aa5f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2014 Symbian Software Systems and others. + * Copyright (c) 2007, 2020 Symbian Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -12,10 +12,12 @@ * Andrew Ferguson (Symbian) - Initial implementation * Markus Schorn (Wind River Systems) * Martin Oberhuber (Wind River) - [397652] fix up-to-date check for PDOM + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.export; import java.io.File; +import java.text.MessageFormat; import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; @@ -33,8 +35,6 @@ import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; -import com.ibm.icu.text.MessageFormat; - /** * An ISafeRunnable which * <ul> diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOMApplication.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOMApplication.java index 91b1f2ab80d..a718f433551 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOMApplication.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOMApplication.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2012 Symbian Software Systems and others. + * Copyright (c) 2007, 2020 Symbian Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -9,13 +9,15 @@ * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Andrew Ferguson (Symbian) - Initial implementation - * Anna Dushistova (MontaVista) - bug [247087] + * Andrew Ferguson (Symbian) - Initial implementation + * Anna Dushistova (MontaVista) - bug [247087] + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.export; import java.io.File; import java.io.PrintStream; +import java.text.MessageFormat; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -40,8 +42,6 @@ import org.eclipse.core.runtime.jobs.ProgressProvider; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; -import com.ibm.icu.text.MessageFormat; - /** * An eclipse application for generating PDOM's without starting the Workbench */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java index 5222cfcaa02..82f28ee5a09 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2016 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2020 Wind River Systems, Inc. and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -12,9 +12,11 @@ * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) * Marc-Andre Laperle (Ericsson) + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.indexer; +import java.text.NumberFormat; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; @@ -47,8 +49,6 @@ import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.osgi.util.NLS; -import com.ibm.icu.text.NumberFormat; - /** * Configures the abstract indexer task suitable for indexing projects. */ |