1 /*
  2  *  Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
  3  *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  *  This code is free software; you can redistribute it and/or modify it
  6  *  under the terms of the GNU General Public License version 2 only, as
  7  *  published by the Free Software Foundation.  Oracle designates this
  8  *  particular file as subject to the "Classpath" exception as provided
  9  *  by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  *  This code is distributed in the hope that it will be useful, but WITHOUT
 12  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  *  version 2 for more details (a copy is included in the LICENSE file that
 15  *  accompanied this code).
 16  *
 17  *  You should have received a copy of the GNU General Public License version
 18  *  2 along with this work; if not, write to the Free Software Foundation,
 19  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  *   Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  *  or visit www.oracle.com if you need additional information or have any
 23  *  questions.
 24  *
 25  */
 26 
 27 package jdk.internal.clang;
 28 
 29 import jdk.incubator.foreign.CLinker;
 30 import jdk.incubator.foreign.MemoryAddress;
 31 import jdk.incubator.foreign.MemorySegment;
 32 import jdk.internal.clang.libclang.Index_h;
 33 
 34 public class EvalResult implements AutoCloseable {
 35     private MemoryAddress ptr;
 36 
 37     public EvalResult(MemoryAddress ptr) {
 38         this.ptr = ptr;
 39     }
 40 
 41     public enum Kind {
 42         Integral,
 43         FloatingPoint,
 44         StrLiteral,
 45         Erroneous,
 46         Unknown
 47     }
 48 
 49     private int getKind0() {
 50         return Index_h.clang_EvalResult_getKind(ptr);
 51     }
 52 
 53     public Kind getKind() {
 54         int code = getKind0();
 55         switch (code) {
 56             case 1: return Kind.Integral;
 57             case 2: return Kind.FloatingPoint;
 58             case 3: case 4: case 5:
 59                 return Kind.StrLiteral;
 60             default:
 61                 return Kind.Unknown;
 62         }
 63     }
 64 
 65     private long getAsInt0() {
 66         return Index_h.clang_EvalResult_getAsLongLong(ptr);
 67     }
 68 
 69     public long getAsInt() {
 70         Kind kind = getKind();
 71         switch (kind) {
 72             case Integral:
 73                 return getAsInt0();
 74             default:
 75                 throw new IllegalStateException("Unexpected kind: " + kind);
 76         }
 77     }
 78 
 79     private double getAsFloat0() {
 80         return Index_h.clang_EvalResult_getAsDouble(ptr);
 81     }
 82 
 83     public double getAsFloat() {
 84         Kind kind = getKind();
 85         switch (kind) {
 86             case FloatingPoint:
 87                 return getAsFloat0();
 88             default:
 89                 throw new IllegalStateException("Unexpected kind: " + kind);
 90         }
 91     }
 92 
 93     private String getAsString0() {
 94         MemoryAddress value = Index_h.clang_EvalResult_getAsStr(ptr);
 95         return value.getUtf8String(0);
 96     }
 97 
 98     public String getAsString() {
 99         Kind kind = getKind();
100         switch (kind) {
101             case StrLiteral:
102                 return getAsString0();
103             default:
104                 throw new IllegalStateException("Unexpected kind: " + kind);
105         }
106     }
107 
108     @Override
109     public void close() {
110         if (ptr != MemoryAddress.NULL) {
111             Index_h.clang_EvalResult_dispose(ptr);
112             ptr = MemoryAddress.NULL;
113         }
114     }
115 
116     final static EvalResult erroneous = new EvalResult(MemoryAddress.NULL) {
117         @Override
118         public Kind getKind() {
119             return Kind.Erroneous;
120         }
121 
122         @Override
123         public void close() {
124             //do nothing
125         }
126     };
127 }