Sfoglia il codice sorgente

Merge pull request #8285 from shamser/issue2819_inline

HPCC-2819 Would be nice to be able to add inline qualifier to embedc++
Gavin Halliday 9 anni fa
parent
commit
8d088dfc70

+ 4 - 0
ecl/hql/hqlexpr.cpp

@@ -12184,6 +12184,10 @@ IHqlExpression * createExternalFuncdefFromInternal(IHqlExpression * funcdef)
     if (functionBodyUsesContext(body))
         attrs.append(*LINK(cachedContextAttribute));
 
+    IHqlExpression *child = body->queryChild(0);
+    if (child && child->getOperator()==no_embedbody)
+        unwindAttribute(attrs, child, inlineAtom);
+
     ITypeInfo * returnType = funcdef->queryType()->queryChildType();
     OwnedHqlExpr externalExpr = createExternalReference(funcdef->queryId(), LINK(returnType), attrs);
     return replaceChild(funcdef, 0, externalExpr);

+ 2 - 0
ecl/hqlcpp/hqlcerrors.hpp

@@ -221,6 +221,7 @@
 #define HQLERR_ConditionalAggregateVarOffset    4201
 #define HQLERR_AggregateDynamicOffset           4202
 #define HQLERR_ServiceDefinitionNotAllowed      4203
+#define HQLERR_BodyNotAllowedWithInline         4204
 
 //Warnings....
 #define HQLWRN_PersistDataNotLikely             4500
@@ -517,6 +518,7 @@
 #define HQLERR_ConditionalAggregateVarOffset_Text "Conditional aggregate '%s' cannot follow a variable length field"
 #define HQLERR_AggregateDynamicOffset_Text      "Aggregate assignment to '%s' cannot follow variable size aggregate"
 #define HQLERR_ServiceDefinitionNotAllowed_Text "Insufficient access rights to use SERVICE"
+#define HQLERR_BodyNotAllowedWithInline_Text    "#body not supported with INLINE attribute"
 
 //Warnings.
 #define HQLWRN_CannotRecreateDistribution_Text  "Cannot recreate the distribution for a persistent dataset"

+ 12 - 1
ecl/hqlcpp/hqlcpp.cpp

@@ -11679,6 +11679,8 @@ void HqlCppTranslator::buildCppFunctionDefinition(BuildCtx &funcctx, IHqlExpress
     const char * separator = strstr(body, cppSeparatorText);
     if (separator)
     {
+        if (bodyCode->hasAttribute(inlineAtom))
+            throwError(HQLERR_BodyNotAllowedWithInline);
         text.setCharAt(separator-text.str(), 0);
         if (location)
             funcctx.addLine(locationFilename, startLine);
@@ -11943,7 +11945,16 @@ void HqlCppTranslator::buildFunctionDefinition(IHqlExpression * funcdef)
         if (languageAttr)
             buildScriptFunctionDefinition(funcctx, funcdef, proto);
         else
-            buildCppFunctionDefinition(funcctx, bodyCode, proto);
+        {
+            bool isInline = bodyCode->hasAttribute(inlineAtom);
+            if (isInline && options.spanMultipleCpp)
+            {
+                BuildCtx funcctx2(*code, parentHelpersAtom);
+                buildCppFunctionDefinition(funcctx2, bodyCode, proto);
+            }
+            else
+                buildCppFunctionDefinition(funcctx, bodyCode, proto);
+        }
     }
     else
     {

+ 9 - 2
ecl/hqlcpp/hqlwcpp.cpp

@@ -593,7 +593,8 @@ bool HqlCppWriter::generateFunctionPrototype(IHqlExpression * funcdef, const cha
     if (body->hasAttribute(_disallowed_Atom))
         throwError(HQLERR_ServiceDefinitionNotAllowed);
 
-    if (body->hasAttribute(includeAtom) || body->hasAttribute(ctxmethodAtom) || body->hasAttribute(gctxmethodAtom) || body->hasAttribute(methodAtom) || body->hasAttribute(sysAtom) || body->hasAttribute(omethodAtom))
+    if (body->hasAttribute(includeAtom) || body->hasAttribute(ctxmethodAtom) || body->hasAttribute(gctxmethodAtom) || body->hasAttribute(methodAtom)
+        || body->hasAttribute(sysAtom) || body->hasAttribute(omethodAtom) || body->hasAttribute(inlineAtom) )
         return false;
 
     IHqlExpression *proto = body->queryAttribute(prototypeAtom);
@@ -607,6 +608,10 @@ bool HqlCppWriter::generateFunctionPrototype(IHqlExpression * funcdef, const cha
     enum { ServiceApi, RtlApi, FastApi, CApi, CppApi, LocalApi } api = ServiceApi;
     bool isVirtual = funcdef->hasAttribute(virtualAtom);
     bool isLocal = body->hasAttribute(localAtom);
+
+    IHqlExpression *child = body->queryChild(0);
+    bool isInline = child?child->hasAttribute(inlineAtom):false;
+
     if (body->hasAttribute(eclrtlAtom))
         api = RtlApi;
     else if (body->hasAttribute(fastAtom))
@@ -618,7 +623,9 @@ bool HqlCppWriter::generateFunctionPrototype(IHqlExpression * funcdef, const cha
     else if (isLocal || isVirtual)
         api = LocalApi;
 
-    if (isVirtual)
+    if (isInline)
+        out.append("inline");
+    else if (isVirtual)
         out.append("virtual");
     else
         out.append("extern");

+ 34 - 0
testing/regress/ecl/embedcppinline.ecl

@@ -0,0 +1,34 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2016 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+//class=embedded
+
+BOOLEAN isUpper(const string mystring) := EMBED(C++ : inline)
+  size_t i=0;
+  while (i < lenMystring)
+  {
+    if (!isupper((byte)mystring[i]))
+        return false;
+    i++;
+  }
+  return true;
+ENDEMBED;
+
+OUTPUT(IsUpper('TOM'));
+
+ds := dataset(4, transform({string1 id}, SELF.id := 'aBcD'[COUNTER]));
+output(TABLE(ds, { isUpper(id) }));

+ 9 - 0
testing/regress/ecl/key/embedcppinline.xml

@@ -0,0 +1,9 @@
+<Dataset name='Result 1'>
+ <Row><Result_1>true</Result_1></Row>
+</Dataset>
+<Dataset name='Result 2'>
+ <Row><isupper>false</isupper></Row>
+ <Row><isupper>true</isupper></Row>
+ <Row><isupper>false</isupper></Row>
+ <Row><isupper>true</isupper></Row>
+</Dataset>