diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td --- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td +++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td @@ -131,6 +131,10 @@ // function. string alternativeName = ""; + // Clauses cannot appear twice in the three allowed lists below. Also, since + // required implies allowed, the same clause cannot appear in both the + // allowedClauses and requiredClauses lists. + // List of allowed clauses for the directive. list allowedClauses = []; diff --git a/llvm/test/TableGen/directive3.td b/llvm/test/TableGen/directive3.td --- a/llvm/test/TableGen/directive3.td +++ b/llvm/test/TableGen/directive3.td @@ -15,16 +15,29 @@ def TDLC_ClauseB : Clause<"clauseb"> { } +def TDLC_ClauseC : Clause<"clausec"> { +} + +def TDLC_ClauseD : Clause<"claused"> { +} + def TDL_DirA : Directive<"dira"> { let allowedClauses = [ VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; let allowedOnceClauses = [ - VersionedClause + VersionedClause, + VersionedClause + ]; + let requiredClauses = [ + VersionedClause, + VersionedClause ]; let isDefault = 1; } // CHECK: error: Clause TDLC_ClauseA already defined on directive TDL_DirA +// CHECK: error: Clause TDLC_ClauseD already defined on directive TDL_DirA // CHECK: error: One or more clauses are defined multiple times on directive TDL_DirA diff --git a/llvm/utils/TableGen/DirectiveEmitter.cpp b/llvm/utils/TableGen/DirectiveEmitter.cpp --- a/llvm/utils/TableGen/DirectiveEmitter.cpp +++ b/llvm/utils/TableGen/DirectiveEmitter.cpp @@ -127,28 +127,40 @@ return hasError; } +// Check for duplicate clauses in lists. Clauses cannot appear twice in the +// three allowed list. Also, since required implies allowed, clauses cannot +// appear in both the allowedClauses and requiredClauses lists. bool HasDuplicateClausesInDirectives(const std::vector &Directives) { + bool hasDuplicate = false; for (const auto &D : Directives) { Directive Dir{D}; llvm::StringSet<> Clauses; + // Check for duplicates in the three allowed lists. if (HasDuplicateClauses(Dir.getAllowedClauses(), Dir, Clauses) || HasDuplicateClauses(Dir.getAllowedOnceClauses(), Dir, Clauses) || - HasDuplicateClauses(Dir.getAllowedExclusiveClauses(), Dir, Clauses) || + HasDuplicateClauses(Dir.getAllowedExclusiveClauses(), Dir, Clauses)) { + hasDuplicate = true; + } + // Check for duplicate between allowedClauses and required + Clauses.clear(); + if (HasDuplicateClauses(Dir.getAllowedClauses(), Dir, Clauses) || HasDuplicateClauses(Dir.getRequiredClauses(), Dir, Clauses)) { - PrintFatalError( - "One or more clauses are defined multiple times on directive " + - Dir.getRecordName()); - return true; + hasDuplicate = true; } + if (hasDuplicate) + PrintFatalError("One or more clauses are defined multiple times on" + " directive " + + Dir.getRecordName()); } - return false; + + return hasDuplicate; } // Check consitency of records. Return true if an error has been detected. // Return false if the records are valid. bool DirectiveLanguage::CheckRecordsValidity() const { if (getDirectiveLanguages().size() != 1) { - PrintError("A single definition of DirectiveLanguage is needed."); + PrintFatalError("A single definition of DirectiveLanguage is needed."); return true; }