From: Daniel Jasper Date: Thu, 20 Dec 2012 20:25:19 +0000 (+0000) Subject: Move operator precedence calculation to new header X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=909610266e67ce40a9d8a4df8be81b3de999b120;p=clang Move operator precedence calculation to new header Thereby, it can be reused by clang-format and others. Review: http://llvm-reviews.chandlerc.com/D229 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170757 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/OperatorPrecedence.h b/include/clang/Basic/OperatorPrecedence.h new file mode 100644 index 0000000000..7dda68365b --- /dev/null +++ b/include/clang/Basic/OperatorPrecedence.h @@ -0,0 +1,52 @@ +//===--- OperatorPrecedence.h - Operator precedence levels ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Defines and computes precedence levels for binary/ternary operators. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_OPERATOR_PRECEDENCE_H +#define LLVM_CLANG_OPERATOR_PRECEDENCE_H + +#include "clang/Basic/TokenKinds.h" + +namespace clang { + +/// PrecedenceLevels - These are precedences for the binary/ternary +/// operators in the C99 grammar. These have been named to relate +/// with the C99 grammar productions. Low precedences numbers bind +/// more weakly than high numbers. +namespace prec { + enum Level { + Unknown = 0, // Not binary operator. + Comma = 1, // , + Assignment = 2, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |= + Conditional = 3, // ? + LogicalOr = 4, // || + LogicalAnd = 5, // && + InclusiveOr = 6, // | + ExclusiveOr = 7, // ^ + And = 8, // & + Equality = 9, // ==, != + Relational = 10, // >=, <=, >, < + Shift = 11, // <<, >> + Additive = 12, // -, + + Multiplicative = 13, // *, /, % + PointerToMember = 14 // .*, ->* + }; +} + +/// \brief Return the precedence of the specified binary operator token. +prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, + bool CPlusPlus0x); + +} // end namespace clang + +#endif // LLVM_CLANG_OPERATOR_PRECEDENCE_H diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 66c1d35cbf..ed8d44be54 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_PARSE_PARSER_H #define LLVM_CLANG_PARSE_PARSER_H +#include "clang/Basic/OperatorPrecedence.h" #include "clang/Basic/Specifiers.h" #include "clang/Lex/CodeCompletionHandler.h" #include "clang/Lex/Preprocessor.h" @@ -44,30 +45,6 @@ namespace clang { class PoisonSEHIdentifiersRAIIObject; class VersionTuple; -/// PrecedenceLevels - These are precedences for the binary/ternary -/// operators in the C99 grammar. These have been named to relate -/// with the C99 grammar productions. Low precedences numbers bind -/// more weakly than high numbers. -namespace prec { - enum Level { - Unknown = 0, // Not binary operator. - Comma = 1, // , - Assignment = 2, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |= - Conditional = 3, // ? - LogicalOr = 4, // || - LogicalAnd = 5, // && - InclusiveOr = 6, // | - ExclusiveOr = 7, // ^ - And = 8, // & - Equality = 9, // ==, != - Relational = 10, // >=, <=, >, < - Shift = 11, // <<, >> - Additive = 12, // -, + - Multiplicative = 13, // *, /, % - PointerToMember = 14 // .*, ->* - }; -} - /// Parser - This implements a parser for the C family of languages. After /// parsing units of the grammar, productions are invoked to handle whatever has /// been read. diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt index 73e693befa..19ec875c05 100644 --- a/lib/Basic/CMakeLists.txt +++ b/lib/Basic/CMakeLists.txt @@ -12,6 +12,7 @@ add_clang_library(clangBasic LangOptions.cpp Module.cpp ObjCRuntime.cpp + OperatorPrecedence.cpp SourceLocation.cpp SourceManager.cpp TargetInfo.cpp diff --git a/lib/Basic/OperatorPrecedence.cpp b/lib/Basic/OperatorPrecedence.cpp new file mode 100644 index 0000000000..f722c2d241 --- /dev/null +++ b/lib/Basic/OperatorPrecedence.cpp @@ -0,0 +1,76 @@ +//===--- OperatorPrecedence.cpp ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Defines and computes precedence levels for binary/ternary operators. +/// +//===----------------------------------------------------------------------===// +#include "clang/Basic/OperatorPrecedence.h" + +namespace clang { + +prec::Level clang::getBinOpPrecedence( + tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus0x) { + switch (Kind) { + case tok::greater: + // C++ [temp.names]p3: + // [...] When parsing a template-argument-list, the first + // non-nested > is taken as the ending delimiter rather than a + // greater-than operator. [...] + if (GreaterThanIsOperator) + return prec::Relational; + return prec::Unknown; + + case tok::greatergreater: + // C++0x [temp.names]p3: + // + // [...] Similarly, the first non-nested >> is treated as two + // consecutive but distinct > tokens, the first of which is + // taken as the end of the template-argument-list and completes + // the template-id. [...] + if (GreaterThanIsOperator || !CPlusPlus0x) + return prec::Shift; + return prec::Unknown; + + default: return prec::Unknown; + case tok::comma: return prec::Comma; + case tok::equal: + case tok::starequal: + case tok::slashequal: + case tok::percentequal: + case tok::plusequal: + case tok::minusequal: + case tok::lesslessequal: + case tok::greatergreaterequal: + case tok::ampequal: + case tok::caretequal: + case tok::pipeequal: return prec::Assignment; + case tok::question: return prec::Conditional; + case tok::pipepipe: return prec::LogicalOr; + case tok::ampamp: return prec::LogicalAnd; + case tok::pipe: return prec::InclusiveOr; + case tok::caret: return prec::ExclusiveOr; + case tok::amp: return prec::And; + case tok::exclaimequal: + case tok::equalequal: return prec::Equality; + case tok::lessequal: + case tok::less: + case tok::greaterequal: return prec::Relational; + case tok::lessless: return prec::Shift; + case tok::plus: + case tok::minus: return prec::Additive; + case tok::percent: + case tok::slash: + case tok::star: return prec::Multiplicative; + case tok::periodstar: + case tok::arrowstar: return prec::PointerToMember; + } +} + +} // namespace clang diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index b7705f8c0d..5229336929 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -32,67 +32,6 @@ #include "llvm/ADT/SmallVector.h" using namespace clang; -/// \brief Return the precedence of the specified binary operator token. -static prec::Level getBinOpPrecedence(tok::TokenKind Kind, - bool GreaterThanIsOperator, - bool CPlusPlus0x) { - switch (Kind) { - case tok::greater: - // C++ [temp.names]p3: - // [...] When parsing a template-argument-list, the first - // non-nested > is taken as the ending delimiter rather than a - // greater-than operator. [...] - if (GreaterThanIsOperator) - return prec::Relational; - return prec::Unknown; - - case tok::greatergreater: - // C++0x [temp.names]p3: - // - // [...] Similarly, the first non-nested >> is treated as two - // consecutive but distinct > tokens, the first of which is - // taken as the end of the template-argument-list and completes - // the template-id. [...] - if (GreaterThanIsOperator || !CPlusPlus0x) - return prec::Shift; - return prec::Unknown; - - default: return prec::Unknown; - case tok::comma: return prec::Comma; - case tok::equal: - case tok::starequal: - case tok::slashequal: - case tok::percentequal: - case tok::plusequal: - case tok::minusequal: - case tok::lesslessequal: - case tok::greatergreaterequal: - case tok::ampequal: - case tok::caretequal: - case tok::pipeequal: return prec::Assignment; - case tok::question: return prec::Conditional; - case tok::pipepipe: return prec::LogicalOr; - case tok::ampamp: return prec::LogicalAnd; - case tok::pipe: return prec::InclusiveOr; - case tok::caret: return prec::ExclusiveOr; - case tok::amp: return prec::And; - case tok::exclaimequal: - case tok::equalequal: return prec::Equality; - case tok::lessequal: - case tok::less: - case tok::greaterequal: return prec::Relational; - case tok::lessless: return prec::Shift; - case tok::plus: - case tok::minus: return prec::Additive; - case tok::percent: - case tok::slash: - case tok::star: return prec::Multiplicative; - case tok::periodstar: - case tok::arrowstar: return prec::PointerToMember; - } -} - - /// \brief Simple precedence-based parser for binary/ternary operators. /// /// Note: we diverge from the C99 grammar when parsing the assignment-expression