137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===- SymbolRewriter.cpp - Symbol Rewriter ---------------------*- C++ -*-===//
237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//                     The LLVM Compiler Infrastructure
437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// This file is distributed under the University of Illinois Open Source
637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// License. See LICENSE.TXT for details.
737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
1037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// SymbolRewriter is a LLVM pass which can rewrite symbols transparently within
1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// existing code.  It is implemented as a compiler pass and is configured via a
1237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// YAML configuration file.
1337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// The YAML configuration file format is as follows:
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteMapFile := RewriteDescriptors
1737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteDescriptors := RewriteDescriptor | RewriteDescriptors
1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteDescriptor := RewriteDescriptorType ':' '{' RewriteDescriptorFields '}'
1937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteDescriptorFields := RewriteDescriptorField | RewriteDescriptorFields
2037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteDescriptorField := FieldIdentifier ':' FieldValue ','
2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteDescriptorType := Identifier
2237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// FieldIdentifier := Identifier
2337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// FieldValue := Identifier
2437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Identifier := [0-9a-zA-Z]+
2537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
2637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Currently, the following descriptor types are supported:
2737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
2837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// - function:          (function rewriting)
2937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//      + Source        (original name of the function)
3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//      + Target        (explicit transformation)
3137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//      + Transform     (pattern transformation)
3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//      + Naked         (boolean, whether the function is undecorated)
3337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// - global variable:   (external linkage global variable rewriting)
3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//      + Source        (original name of externally visible variable)
3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//      + Target        (explicit transformation)
3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//      + Transform     (pattern transformation)
3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// - global alias:      (global alias rewriting)
3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//      + Source        (original name of the aliased name)
3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//      + Target        (explicit transformation)
4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//      + Transform     (pattern transformation)
4137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Note that source and exactly one of [Target, Transform] must be provided
4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// New rewrite descriptors can be created.  Addding a new rewrite descriptor
4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// involves:
4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//  a) extended the rewrite descriptor kind enumeration
4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//     (<anonymous>::RewriteDescriptor::RewriteDescriptorType)
4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//  b) implementing the new descriptor
5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//     (c.f. <anonymous>::ExplicitRewriteFunctionDescriptor)
5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//  c) extending the rewrite map parser
5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//     (<anonymous>::RewriteMapParser::parseEntry)
5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//  Specify to rewrite the symbols using the `-rewrite-symbols` option, and
5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//  specify the map file to use for the rewriting via the `-rewrite-map-file`
5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//  option.
5737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
5837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define DEBUG_TYPE "symbol-rewriter"
6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/CodeGen/Passes.h"
6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Pass.h"
634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/SmallString.h"
64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/LegacyPassManager.h"
6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/CommandLine.h"
6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Debug.h"
6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/MemoryBuffer.h"
6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Regex.h"
6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/SourceMgr.h"
7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/YAMLParser.h"
7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/raw_ostream.h"
7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Transforms/Utils/SymbolRewriter.h"
7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesusing namespace llvm;
754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarusing namespace SymbolRewriter;
7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::list<std::string> RewriteMapFiles("rewrite-map-file",
7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                             cl::desc("Symbol Rewrite Map"),
7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                             cl::value_desc("filename"));
8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic void rewriteComdat(Module &M, GlobalObject *GO,
824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                          const std::string &Source,
834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                          const std::string &Target) {
84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Comdat *CD = GO->getComdat()) {
85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    auto &Comdats = M.getComdatSymbolTable();
86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Comdat *C = M.getOrInsertComdat(Target);
88ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    C->setSelectionKind(CD->getSelectionKind());
89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    GO->setComdat(C);
90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Comdats.erase(Comdats.find(Source));
92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarnamespace {
9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <RewriteDescriptor::Type DT, typename ValueType,
9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          ValueType *(llvm::Module::*Get)(StringRef) const>
9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass ExplicitRewriteDescriptor : public RewriteDescriptor {
9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic:
10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const std::string Source;
10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const std::string Target;
10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ExplicitRewriteDescriptor(StringRef S, StringRef T, const bool Naked)
10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      : RewriteDescriptor(DT), Source(Naked ? StringRef("\01" + S.str()) : S),
10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Target(T) {}
10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool performOnModule(Module &M) override;
10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  static bool classof(const RewriteDescriptor *RD) {
11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return RD->getType() == DT;
11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <RewriteDescriptor::Type DT, typename ValueType,
11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          ValueType *(llvm::Module::*Get)(StringRef) const>
11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {
11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool Changed = false;
11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ValueType *S = (M.*Get)(Source)) {
119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (GlobalObject *GO = dyn_cast<GlobalObject>(S))
120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      rewriteComdat(M, GO, Source, Target);
121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
12237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Value *T = (M.*Get)(Target))
12337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      S->setValueName(T->getValueName());
12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      S->setName(Target);
126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Changed = true;
12837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
12937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Changed;
13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
13237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <RewriteDescriptor::Type DT, typename ValueType,
13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          ValueType *(llvm::Module::*Get)(StringRef) const,
134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          iterator_range<typename iplist<ValueType>::iterator>
135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          (llvm::Module::*Iterator)()>
13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass PatternRewriteDescriptor : public RewriteDescriptor {
13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic:
13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const std::string Pattern;
13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const std::string Transform;
14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  PatternRewriteDescriptor(StringRef P, StringRef T)
14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    : RewriteDescriptor(DT), Pattern(P), Transform(T) { }
14337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool performOnModule(Module &M) override;
14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  static bool classof(const RewriteDescriptor *RD) {
14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return RD->getType() == DT;
14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <RewriteDescriptor::Type DT, typename ValueType,
15237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          ValueType *(llvm::Module::*Get)(StringRef) const,
153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          iterator_range<typename iplist<ValueType>::iterator>
154ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          (llvm::Module::*Iterator)()>
15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>::
15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesperformOnModule(Module &M) {
15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool Changed = false;
15837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (auto &C : (M.*Iterator)()) {
15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    std::string Error;
16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    std::string Name = Regex(Pattern).sub(Transform, C.getName(), &Error);
16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Error.empty())
16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      report_fatal_error("unable to transforn " + C.getName() + " in " +
16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         M.getModuleIdentifier() + ": " + Error);
16537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
166ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (C.getName() == Name)
167ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      continue;
168ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (GlobalObject *GO = dyn_cast<GlobalObject>(&C))
170ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      rewriteComdat(M, GO, C.getName(), Name);
171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Value *V = (M.*Get)(Name))
17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      C.setValueName(V->getValueName());
17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      C.setName(Name);
17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Changed = true;
17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Changed;
18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Represents a rewrite for an explicitly named (function) symbol.  Both the
18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// source function name and target function name of the transformation are
18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// explicitly spelt out.
18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function,
18637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  llvm::Function, &llvm::Module::getFunction>
18737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ExplicitRewriteFunctionDescriptor;
18837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
18937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Represents a rewrite for an explicitly named (global variable) symbol.  Both
19037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// the source variable name and target variable name are spelt out.  This
19137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// applies only to module level variables.
19237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
19337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  llvm::GlobalVariable,
19437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  &llvm::Module::getGlobalVariable>
19537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ExplicitRewriteGlobalVariableDescriptor;
19637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
19737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Represents a rewrite for an explicitly named global alias.  Both the source
19837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// and target name are explicitly spelt out.
19937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
20037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  llvm::GlobalAlias,
20137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  &llvm::Module::getNamedAlias>
20237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ExplicitRewriteNamedAliasDescriptor;
20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
20437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Represents a rewrite for a regular expression based pattern for functions.
20537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// A pattern for the function name is provided and a transformation for that
20637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// pattern to determine the target function name create the rewrite rule.
20737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef PatternRewriteDescriptor<RewriteDescriptor::Type::Function,
20837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 llvm::Function, &llvm::Module::getFunction,
20937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 &llvm::Module::functions>
21037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    PatternRewriteFunctionDescriptor;
21137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
21237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Represents a rewrite for a global variable based upon a matching pattern.
21337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Each global variable matching the provided pattern will be transformed as
21437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// described in the transformation pattern for the target.  Applies only to
21537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// module level variables.
21637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 llvm::GlobalVariable,
21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 &llvm::Module::getGlobalVariable,
21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 &llvm::Module::globals>
22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    PatternRewriteGlobalVariableDescriptor;
22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
22237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// PatternRewriteNamedAliasDescriptor - represents a rewrite for global
22337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// aliases which match a given pattern.  The provided transformation will be
22437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// applied to each of the matching names.
22537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
22637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 llvm::GlobalAlias,
22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 &llvm::Module::getNamedAlias,
22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 &llvm::Module::aliases>
22937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    PatternRewriteNamedAliasDescriptor;
2304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} // namespace
23137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
23237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser::parse(const std::string &MapFile,
23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             RewriteDescriptorList *DL) {
23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ErrorOr<std::unique_ptr<MemoryBuffer>> Mapping =
23537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MemoryBuffer::getFile(MapFile);
23637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
23737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!Mapping)
23837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    report_fatal_error("unable to read rewrite map '" + MapFile + "': " +
23937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       Mapping.getError().message());
24037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
24137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!parse(*Mapping, DL))
24237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    report_fatal_error("unable to parse rewrite map '" + MapFile + "'");
24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
24437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return true;
24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
24737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser::parse(std::unique_ptr<MemoryBuffer> &MapFile,
24837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             RewriteDescriptorList *DL) {
24937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SourceMgr SM;
25037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  yaml::Stream YS(MapFile->getBuffer(), SM);
25137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
25237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (auto &Document : YS) {
25337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    yaml::MappingNode *DescriptorList;
25437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // ignore empty documents
25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (isa<yaml::NullNode>(Document.getRoot()))
25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DescriptorList = dyn_cast<yaml::MappingNode>(Document.getRoot());
26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!DescriptorList) {
26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      YS.printError(Document.getRoot(), "DescriptorList node must be a map");
26237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
26337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
26437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
26537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (auto &Descriptor : *DescriptorList)
26637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!parseEntry(YS, Descriptor, DL))
26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return false;
26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return true;
27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
27237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
27337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry,
27437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  RewriteDescriptorList *DL) {
27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  yaml::ScalarNode *Key;
27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  yaml::MappingNode *Value;
27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallString<32> KeyStorage;
27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef RewriteType;
27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Key = dyn_cast<yaml::ScalarNode>(Entry.getKey());
28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!Key) {
28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    YS.printError(Entry.getKey(), "rewrite type must be a scalar");
28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Value = dyn_cast<yaml::MappingNode>(Entry.getValue());
28737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!Value) {
28837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    YS.printError(Entry.getValue(), "rewrite descriptor must be a map");
28937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
29037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
29137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
29237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  RewriteType = Key->getValue(KeyStorage);
29337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (RewriteType.equals("function"))
29437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseRewriteFunctionDescriptor(YS, Key, Value, DL);
29537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (RewriteType.equals("global variable"))
29637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL);
29737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (RewriteType.equals("global alias"))
29837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL);
29937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
30037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  YS.printError(Entry.getKey(), "unknown rewrite type");
30137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return false;
30237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
30337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser::
30537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesparseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
30637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               yaml::MappingNode *Descriptor,
30737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               RewriteDescriptorList *DL) {
30837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool Naked = false;
30937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string Source;
31037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string Target;
31137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string Transform;
31237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
31337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (auto &Field : *Descriptor) {
31437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    yaml::ScalarNode *Key;
31537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    yaml::ScalarNode *Value;
31637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SmallString<32> KeyStorage;
31737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SmallString<32> ValueStorage;
31837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef KeyValue;
31937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
32037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
32137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Key) {
32237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      YS.printError(Field.getKey(), "descriptor key must be a scalar");
32337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
32437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
32537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
32637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
32737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Value) {
32837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      YS.printError(Field.getValue(), "descriptor value must be a scalar");
32937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
33037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
33137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
33237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    KeyValue = Key->getValue(KeyStorage);
33337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (KeyValue.equals("source")) {
33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      std::string Error;
33537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
33637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Source = Value->getValue(ValueStorage);
33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!Regex(Source).isValid(Error)) {
33837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        YS.printError(Field.getKey(), "invalid regex: " + Error);
33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return false;
34037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
34137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (KeyValue.equals("target")) {
34237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Target = Value->getValue(ValueStorage);
34337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (KeyValue.equals("transform")) {
34437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Transform = Value->getValue(ValueStorage);
34537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (KeyValue.equals("naked")) {
34637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      std::string Undecorated;
34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
34837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Undecorated = Value->getValue(ValueStorage);
34937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Naked = StringRef(Undecorated).lower() == "true" || Undecorated == "1";
35037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else {
35137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      YS.printError(Field.getKey(), "unknown key for function");
35237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
35337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
35437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
35537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
35637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Transform.empty() == Target.empty()) {
35737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    YS.printError(Descriptor,
35837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                  "exactly one of transform or target must be specified");
35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
36037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
36137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
36237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // TODO see if there is a more elegant solution to selecting the rewrite
36337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // descriptor type
36437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!Target.empty())
36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DL->push_back(new ExplicitRewriteFunctionDescriptor(Source, Target, Naked));
36637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
36737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DL->push_back(new PatternRewriteFunctionDescriptor(Source, Transform));
36837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
36937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return true;
37037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
37137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
37237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser::
37337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesparseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
37437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                     yaml::MappingNode *Descriptor,
37537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                     RewriteDescriptorList *DL) {
37637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string Source;
37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string Target;
37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string Transform;
37937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
38037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (auto &Field : *Descriptor) {
38137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    yaml::ScalarNode *Key;
38237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    yaml::ScalarNode *Value;
38337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SmallString<32> KeyStorage;
38437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SmallString<32> ValueStorage;
38537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef KeyValue;
38637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
38737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
38837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Key) {
38937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      YS.printError(Field.getKey(), "descriptor Key must be a scalar");
39037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
39137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
39237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
39337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
39437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Value) {
39537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      YS.printError(Field.getValue(), "descriptor value must be a scalar");
39637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
39737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
39837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
39937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    KeyValue = Key->getValue(KeyStorage);
40037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (KeyValue.equals("source")) {
40137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      std::string Error;
40237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
40337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Source = Value->getValue(ValueStorage);
40437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!Regex(Source).isValid(Error)) {
40537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        YS.printError(Field.getKey(), "invalid regex: " + Error);
40637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return false;
40737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
40837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (KeyValue.equals("target")) {
40937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Target = Value->getValue(ValueStorage);
41037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (KeyValue.equals("transform")) {
41137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Transform = Value->getValue(ValueStorage);
41237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else {
41337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      YS.printError(Field.getKey(), "unknown Key for Global Variable");
41437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
41537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
41637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
41737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
41837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Transform.empty() == Target.empty()) {
41937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    YS.printError(Descriptor,
42037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                  "exactly one of transform or target must be specified");
42137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
42237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
42337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
42437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!Target.empty())
42537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DL->push_back(new ExplicitRewriteGlobalVariableDescriptor(Source, Target,
42637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                              /*Naked*/false));
42737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
42837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DL->push_back(new PatternRewriteGlobalVariableDescriptor(Source,
42937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                             Transform));
43037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
43137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return true;
43237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
43337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
43437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser::
43537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesparseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
43637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  yaml::MappingNode *Descriptor,
43737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  RewriteDescriptorList *DL) {
43837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string Source;
43937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string Target;
44037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string Transform;
44137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
44237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (auto &Field : *Descriptor) {
44337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    yaml::ScalarNode *Key;
44437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    yaml::ScalarNode *Value;
44537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SmallString<32> KeyStorage;
44637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SmallString<32> ValueStorage;
44737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef KeyValue;
44837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
44937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
45037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Key) {
45137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      YS.printError(Field.getKey(), "descriptor key must be a scalar");
45237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
45337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
45437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
45537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
45637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Value) {
45737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      YS.printError(Field.getValue(), "descriptor value must be a scalar");
45837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
45937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
46037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
46137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    KeyValue = Key->getValue(KeyStorage);
46237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (KeyValue.equals("source")) {
46337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      std::string Error;
46437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
46537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Source = Value->getValue(ValueStorage);
46637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!Regex(Source).isValid(Error)) {
46737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        YS.printError(Field.getKey(), "invalid regex: " + Error);
46837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return false;
46937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
47037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (KeyValue.equals("target")) {
47137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Target = Value->getValue(ValueStorage);
47237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (KeyValue.equals("transform")) {
47337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Transform = Value->getValue(ValueStorage);
47437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else {
47537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      YS.printError(Field.getKey(), "unknown key for Global Alias");
47637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
47737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
47837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
47937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
48037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Transform.empty() == Target.empty()) {
48137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    YS.printError(Descriptor,
48237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                  "exactly one of transform or target must be specified");
48337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
48437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
48537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
48637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!Target.empty())
48737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DL->push_back(new ExplicitRewriteNamedAliasDescriptor(Source, Target,
48837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                          /*Naked*/false));
48937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
49037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DL->push_back(new PatternRewriteNamedAliasDescriptor(Source, Transform));
49137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
49237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return true;
49337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
49437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
49537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesnamespace {
49637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass RewriteSymbols : public ModulePass {
49737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic:
49837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  static char ID; // Pass identification, replacement for typeid
49937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
50037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  RewriteSymbols();
50137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL);
50237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
50337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool runOnModule(Module &M) override;
50437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
50537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesprivate:
50637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void loadAndParseMapFiles();
50737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
50837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SymbolRewriter::RewriteDescriptorList Descriptors;
50937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
51037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
51137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hineschar RewriteSymbols::ID = 0;
51237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
51337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesRewriteSymbols::RewriteSymbols() : ModulePass(ID) {
51437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  initializeRewriteSymbolsPass(*PassRegistry::getPassRegistry());
51537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  loadAndParseMapFiles();
51637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
51737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
51837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesRewriteSymbols::RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL)
51937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    : ModulePass(ID) {
520ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Descriptors.splice(Descriptors.begin(), DL);
52137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
52237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
52337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteSymbols::runOnModule(Module &M) {
52437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool Changed;
52537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
52637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Changed = false;
52737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (auto &Descriptor : Descriptors)
52837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Changed |= Descriptor.performOnModule(M);
52937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
53037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Changed;
53137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
53237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
53337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid RewriteSymbols::loadAndParseMapFiles() {
53437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const std::vector<std::string> MapFiles(RewriteMapFiles);
53537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SymbolRewriter::RewriteMapParser parser;
53637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
53737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const auto &MapFile : MapFiles)
53837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    parser.parse(MapFile, &Descriptors);
53937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
54037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
54137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
54237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesINITIALIZE_PASS(RewriteSymbols, "rewrite-symbols", "Rewrite Symbols", false,
54337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                false)
54437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
54537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesModulePass *llvm::createRewriteSymbolsPass() { return new RewriteSymbols(); }
54637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
54737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesModulePass *
54837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesllvm::createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &DL) {
54937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return new RewriteSymbols(DL);
55037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
551