|
| 1 | +diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def |
| 2 | +index ad366821f..86c99507d 100644 |
| 3 | +--- a/clang/include/clang/Basic/LangOptions.def |
| 4 | ++++ b/clang/include/clang/Basic/LangOptions.def |
| 5 | +@@ -309,6 +309,8 @@ LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math") |
| 6 | + BENIGN_LANGOPT(CLNoSignedZero , 1, 0, "Permit Floating Point optimization without regard to signed zeros") |
| 7 | + COMPATIBLE_LANGOPT(CLUnsafeMath , 1, 0, "Unsafe Floating Point Math") |
| 8 | + COMPATIBLE_LANGOPT(CLFiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro") |
| 9 | ++ |
| 10 | ++LANGOPT(UnknownAttrAnnotate, 1, 0, "Unknown attributes are treated as annotation or annotation type attributes during semantic analysis") |
| 11 | + /// FP_CONTRACT mode (on/off/fast). |
| 12 | + BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type") |
| 13 | + COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict floating point") |
| 14 | +diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td |
| 15 | +index 3cab37b21..71a6a6600 100644 |
| 16 | +--- a/clang/include/clang/Driver/Options.td |
| 17 | ++++ b/clang/include/clang/Driver/Options.td |
| 18 | +@@ -4277,6 +4277,11 @@ def working_directory : JoinedOrSeparate<["-"], "working-directory">, Flags<[CC1 |
| 19 | + def working_directory_EQ : Joined<["-"], "working-directory=">, Flags<[CC1Option]>, |
| 20 | + Alias<working_directory>; |
| 21 | + |
| 22 | ++def funknown_attrs_as_annotate : Flag<["-"], "funknown-attrs-as-annotate">, |
| 23 | ++ Flags<[CC1Option]>, |
| 24 | ++ HelpText<"Treat unknown attributes as annotation or annotation type attributes in semantic analysis">, |
| 25 | ++ MarshallingInfoFlag<LangOpts<"UnknownAttrAnnotate">>; |
| 26 | ++ |
| 27 | + // Double dash options, which are usually an alias for one of the previous |
| 28 | + // options. |
| 29 | + |
| 30 | +diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp |
| 31 | +index 3704ed858..ae3935cc5 100644 |
| 32 | +--- a/clang/lib/Driver/ToolChains/Clang.cpp |
| 33 | ++++ b/clang/lib/Driver/ToolChains/Clang.cpp |
| 34 | +@@ -4595,6 +4595,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, |
| 35 | + } |
| 36 | + } |
| 37 | + |
| 38 | ++ if (const Arg *A = Args.getLastArg(options::OPT_funknown_attrs_as_annotate)) { |
| 39 | ++ CmdArgs.push_back("-funknown-attrs-as-annotate"); |
| 40 | ++ A->claim(); |
| 41 | ++ } |
| 42 | ++ |
| 43 | + if (IsOpenMPDevice) { |
| 44 | + // We have to pass the triple of the host if compiling for an OpenMP device. |
| 45 | + std::string NormalizedTriple = |
| 46 | +diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp |
| 47 | +index bf73ddfd1..b2832d4fc 100644 |
| 48 | +--- a/clang/lib/Parse/ParseDeclCXX.cpp |
| 49 | ++++ b/clang/lib/Parse/ParseDeclCXX.cpp |
| 50 | +@@ -4276,18 +4276,22 @@ bool Parser::ParseCXX11AttributeArgs( |
| 51 | + Syntax = ParsedAttr::AS_Microsoft; |
| 52 | + } |
| 53 | + |
| 54 | ++ |
| 55 | + // If the attribute isn't known, we will not attempt to parse any |
| 56 | +- // arguments. |
| 57 | +- if (Syntax != ParsedAttr::AS_Microsoft && |
| 58 | +- !hasAttribute(LO.CPlusPlus ? AttributeCommonInfo::Syntax::AS_CXX11 |
| 59 | +- : AttributeCommonInfo::Syntax::AS_C2x, |
| 60 | +- ScopeName, AttrName, getTargetInfo(), getLangOpts())) { |
| 61 | +- if (getLangOpts().MicrosoftExt || getLangOpts().HLSL) { |
| 62 | ++ // arguments. Unless we are treating unknown attributes as annotation |
| 63 | ++ // attributes. |
| 64 | ++ if (!getLangOpts().UnknownAttrAnnotate) { |
| 65 | ++ if (Syntax != ParsedAttr::AS_Microsoft && |
| 66 | ++ !hasAttribute(LO.CPlusPlus ? AttributeCommonInfo::Syntax::AS_CXX11 |
| 67 | ++ : AttributeCommonInfo::Syntax::AS_C2x, |
| 68 | ++ ScopeName, AttrName, getTargetInfo(), getLangOpts())) { |
| 69 | ++ if (getLangOpts().MicrosoftExt || getLangOpts().HLSL) { |
| 70 | ++ } |
| 71 | ++ // Eat the left paren, then skip to the ending right paren. |
| 72 | ++ ConsumeParen(); |
| 73 | ++ SkipUntil(tok::r_paren); |
| 74 | ++ return false; |
| 75 | + } |
| 76 | +- // Eat the left paren, then skip to the ending right paren. |
| 77 | +- ConsumeParen(); |
| 78 | +- SkipUntil(tok::r_paren); |
| 79 | +- return false; |
| 80 | + } |
| 81 | + |
| 82 | + if (ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"))) { |
| 83 | +diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp |
| 84 | +index 838fd4835..e8efeba90 100644 |
| 85 | +--- a/clang/lib/Sema/SemaDeclAttr.cpp |
| 86 | ++++ b/clang/lib/Sema/SemaDeclAttr.cpp |
| 87 | +@@ -4168,6 +4168,21 @@ static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) { |
| 88 | + S.AddAnnotationAttr(D, AL, Str, Args); |
| 89 | + } |
| 90 | + |
| 91 | ++static void |
| 92 | ++handleUnknownAttrAsAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) { |
| 93 | ++ // Get name of unknown attribute: |
| 94 | ++ StringRef Str = AL.getAttrName()->getName(); |
| 95 | ++ |
| 96 | ++ llvm::SmallVector<Expr *, 4> Args; |
| 97 | ++ Args.reserve(AL.getNumArgs()); |
| 98 | ++ for (unsigned Idx = 0; Idx < AL.getNumArgs(); Idx++) { |
| 99 | ++ assert(!AL.isArgIdent(Idx)); |
| 100 | ++ Args.push_back(AL.getArgAsExpr(Idx)); |
| 101 | ++ } |
| 102 | ++ |
| 103 | ++ S.AddAnnotationAttr(D, AL, Str, Args); |
| 104 | ++} |
| 105 | ++ |
| 106 | + static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) { |
| 107 | + S.AddAlignValueAttr(D, AL, AL.getArgAsExpr(0)); |
| 108 | + } |
| 109 | +@@ -8355,11 +8370,15 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, |
| 110 | + // though they were unknown attributes. |
| 111 | + if (AL.getKind() == ParsedAttr::UnknownAttribute || |
| 112 | + !AL.existsInTarget(S.Context.getTargetInfo())) { |
| 113 | +- S.Diag(AL.getLoc(), |
| 114 | +- AL.isDeclspecAttribute() |
| 115 | ++ if (S.getLangOpts().UnknownAttrAnnotate) { |
| 116 | ++ handleUnknownAttrAsAnnotateAttr(S, D, AL); |
| 117 | ++ } else { |
| 118 | ++ S.Diag(AL.getLoc(), |
| 119 | ++ AL.isDeclspecAttribute() |
| 120 | + ? (unsigned)diag::warn_unhandled_ms_attribute_ignored |
| 121 | + : (unsigned)diag::warn_unknown_attribute_ignored) |
| 122 | +- << AL << AL.getRange(); |
| 123 | ++ << AL << AL.getRange(); |
| 124 | ++ } |
| 125 | + return; |
| 126 | + } |
| 127 | + |
| 128 | +diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp |
| 129 | +index edcac4d2e..9ed87b45d 100644 |
| 130 | +--- a/clang/lib/Sema/SemaType.cpp |
| 131 | ++++ b/clang/lib/Sema/SemaType.cpp |
| 132 | +@@ -8186,6 +8186,24 @@ static void HandleMatrixTypeAttr(QualType &CurType, const ParsedAttr &Attr, |
| 133 | + CurType = T; |
| 134 | + } |
| 135 | + |
| 136 | ++static void HandleUnkownTypeAttrAsAnnotateTypeAttr(TypeProcessingState &State, |
| 137 | ++ QualType &CurType, const ParsedAttr &PA) { |
| 138 | ++ Sema &S = State.getSema(); |
| 139 | ++ StringRef Str = PA.getAttrName()->getName(); |
| 140 | ++ |
| 141 | ++ llvm::SmallVector<Expr *, 4> Args; |
| 142 | ++ Args.reserve(PA.getNumArgs()); |
| 143 | ++ for (unsigned Idx = 0; Idx < PA.getNumArgs(); Idx++) { |
| 144 | ++ assert(!PA.isArgIdent(Idx)); |
| 145 | ++ Args.push_back(PA.getArgAsExpr(Idx)); |
| 146 | ++ } |
| 147 | ++ if (!S.ConstantFoldAttrArgs(PA, Args)) |
| 148 | ++ return; |
| 149 | ++ auto *AnnotateTypeAttr = |
| 150 | ++ AnnotateTypeAttr::Create(S.Context, Str, Args.data(), Args.size(), PA); |
| 151 | ++ CurType = State.getAttributedType(AnnotateTypeAttr, CurType, CurType); |
| 152 | ++} |
| 153 | ++ |
| 154 | + static void HandleAnnotateTypeAttr(TypeProcessingState &State, |
| 155 | + QualType &CurType, const ParsedAttr &PA) { |
| 156 | + Sema &S = State.getSema(); |
| 157 | +@@ -8289,12 +8307,17 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, |
| 158 | + |
| 159 | + case ParsedAttr::UnknownAttribute: |
| 160 | + if (attr.isStandardAttributeSyntax()) { |
| 161 | +- state.getSema().Diag(attr.getLoc(), |
| 162 | +- diag::warn_unknown_attribute_ignored) |
| 163 | +- << attr << attr.getRange(); |
| 164 | +- // Mark the attribute as invalid so we don't emit the same diagnostic |
| 165 | +- // multiple times. |
| 166 | +- attr.setInvalid(); |
| 167 | ++ if (state.getSema().getLangOpts().UnknownAttrAnnotate) { |
| 168 | ++ HandleUnkownTypeAttrAsAnnotateTypeAttr(state, type, attr); |
| 169 | ++ attr.setUsedAsTypeAttr(); |
| 170 | ++ } else { |
| 171 | ++ state.getSema().Diag(attr.getLoc(), |
| 172 | ++ diag::warn_unknown_attribute_ignored) |
| 173 | ++ << attr << attr.getRange(); |
| 174 | ++ // Mark the attribute as invalid so we don't emit the same diagnostic |
| 175 | ++ // multiple times. |
| 176 | ++ attr.setInvalid(); |
| 177 | ++ } |
| 178 | + } |
| 179 | + break; |
| 180 | + |
0 commit comments